天天看点

黑马程序员-面向对象 多态,内部类

------- android培训、 java培训、期待与您交流! ----------

18,多态

     多态:可以理解为事物存在的多种体现形态。

      1,多态的体现。

             父类的引用指向了自己子类对象。

            父类的引用也可以接收自己的子类的对象。

      2,多态的前提。

            必须是类与类之间有关系,要么继承,要么实现。

            存在覆盖

      3,多态的好处。

              多态的出现大大提高了程序的扩展性。

       4,弊端

               提高了扩展性,但是只能使用父类的引用访问父类中的成员。

      5,多态的应用。

    转型:

             Cat类中有一个特有的方法CatchMouse();

             Animal a=new Cat();//类型提升。向上转型

              a.eat();

              //如果想要调用子类特有的方法时,如何操作?

             //强制将父类的引用。转成子类类型.向下转型。

             //我们能转换的是父类引用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。

              //多态自始自终都是子类对象在做着变化。

              Car c=(Car)a;

              c.catchMouse();

                    判断某一类型 引用指向的对象到底符合什么类型的时候

                  if(a instanceof Cat){

                             Cat c=(Cat)a;

                             c.catchMouse();

                      }

6,成员特点。

        在编译时期:参阅引用型变量所属的类中是否有调用德尔方法。如果有,编译通过,没有编译失败。

         在运行时期:参阅对象所属的类中是否有调用的方法。

         简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。

       在多态中,成员变量的特点:(非静态的)

           无论编译和运行,都参考左边。(引用型变量所属的类)

             父类有一个变量num,子类有一个变量num

                 Fu f=new Zi();

                   f.num是父类中的num;

              Zi zi=new ZI();

                 zi.num是子类中的num;

       在多态中静态成员函数的特点:

           无论编译和运行,都参考左边。

                  类加载到内存,静态就存在了,不需要对象。

19,Object :是所有对象的直接或者间接父类,传说的上帝。

          该类中定义的肯定是所有对象都具备的功能。

         Object 类中已经提供了对对象是否相同的比较方法。

         如果自定义类中也有比较相同的功能,没有必要重新定义。

         如果沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。

        equals(); toString();

20,内部类

将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。

 内部类与外部类的访问规则

/*
 * 内部类的访问规则
 * 1,内部类可以直接访问外部类中的成员,包括私有
 *     之所以可以直接访问外部类的成员,是因为内部类中持有了外部类的引用。外部类.this
 * 2,外部类要访问内部类,必须建立内部类对象。
 */
public class InnerClassDemo {

	public static void main(String[] args) {
		// Outer o=new Outer();
		// o.method();
		// 直接访问内部类的成员。
		Outer.Iner in = new Outer().new Iner();
		in.function();
	}
}

class Outer {
	private int x = 3;

	// 内部类可以私有化
	class Iner {
		int x = 4;

		public void function() {
			int x = 6;
			System.out.println("inner" + x);// 这里打印6,内部有的不往外找了
			System.out.println("inner" + this.x);// 这里打印4;
			System.out.println("inner" + Outer.this.x);// 这里打印6
		}
	}

	public void method() {
		Iner i = new Iner();
		i.function();
	}
}
           

访问格式:

1,当内部类定义在外部类的成员位置上,而且非私有的,可以再外部其他类中,可以直接建立内部类对象。

  格式:

         外部类.内部类名 变量名=外部类对象.内部类对象;

2,当内部类在成员位置上,就可以被成员修饰符所修饰。

       比如,private :将内部类在外部类中进行封装。

            static :内部类就具备static 的特性。

            当内部类被static 修饰后,只能直接访问外部类中的static成员了。出现了访问权限、

           在外部其他类中,如何直接访问static内部类的非静态成员呢?

           new Outer.Inner().function();;

          在外部其他类中,如何直接访问static内部类的静态成员呢?

            Outer.Inner.function();

          注意:当内部类中定义了静态成员,该内部类就必须是static的。

内部类定义规则。

      当描述事物时,事物的内部还有事物,该事物用内部类来描述。

          因为内部事物在使用外部事物的内容。

      内部类只有定义在成员变量上的时候,才能被私有或者静态所修饰,一般内部类是不会被公有修饰的。

21,匿名内部类

     在方法当中定义内部类

public class InnerClassDemo {
	public static void main(String[] args) {
         Outer o=new Outer();
         o.method(7);
         o.method(6);
	}
}
/*
 * 内部类定义在局部时
 * 1,不可以被成员修饰符修饰
 * 2,可以直接访问外部类中的成员,因为还持有外部类的引用。
 *       但是不可以访问他所在的局部中的变量。只能访问被final修饰的局部变量
 *
 */
class Outer {
	int x = 3;
  
	void method(final int a) {
	  final	int y=4;
		/**
		 * 此时不能被静态私有修饰,因为修饰符只能修饰成员,现在Inner在局部了,所以不能
		 * @author Administrator
		 */
		class Inner {
			/**
			 * 这里也不能用static修饰
			 */
			void function() {
				System.out.println(Outer.this.x);
				System.out.println(y);//加final
				System.out.println(a);//加final
			}
		}
		new Inner().function();
	}
}
           

匿名内部类:

        1,匿名内部类其实就是内部类的简写格式。

        2,定义匿名内部类的前提;

                内部类必须是继承一个类或者接口。

        3,   匿名内部类的格式,new 父类或者接口(){定义子类的内容}

        4 ,     其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖,也可以理解为带内容的对象。

         5,匿名内部类中定义的方法最好不要超过三个。

public class InnerClassDemo {
	public static void main(String[] args) {
		new Outer().function();
	}
}

class Outer {
	int x = 3;

	/*
	 * class Inner extends AbsDemo{ void show(){ System.out.println("show:"+x);
	 * } }
	 */
	// 对上面的代码简化
	public void function() {
		// new Inner().show();
		/*
		 * 整体是一个对象,是AbsDemo的一个子类对象,只有之类才能复写方法。
		 */
		new AbsDemo() {// 匿名内部类

			@Override
			void show() {// 复写方法
				// TODO Auto-generated method stub
				System.out.println("x:" + x);
			}

		}.show();
	}
}

abstract class AbsDemo {
	abstract void show();
}
           

基本小练习

public class InnerClassDemo {
	public static void main(String[] args) {
		// 类名. 肯定有静态成员Test.function(),有一个静态的方法。
		// .method;function 这个方法运算后的结果是一个对象,而是一个Inter对象
		// 只有Inter才能调用mthod方法。
		Test.function().method();

	}
}

interface Inter {
	void method();
}

class Test {
	// 补足代码。通过匿名内部类
	/*
	 * static class Inner implements Inter{
	 * 
	 * @Override public void method() { // TODO Auto-generated method stub
	 * System.out.println("method run"); }
	 * 
	 * }
	 */
	static Inter function() {
		// return new Inner();
		return new Inter() {

			@Override
			public void method() {
				// TODO Auto-generated method stub
				System.out.println("method run");
			}

		};
	}

}
           

关于内部类的概述总结

内部类有两种情况: (1) 在类中定义一个类(私有内部类,静态内部类) (2) 在方法中定义一个类(局部内部类,匿名内部类)   1、私有内部类 —— 在方法之间定义的内部类,非静态       我们首先看看类中内部类的两个特点:       (1) 在外部类的作用范围内可以任意创建内部类对象,即使内部类是私有的(私有内部类)。即内部类对包围它的外部类可见。 例如 (实际上,内部类是可以设置为public公开的,但一般我是当做成员变量设置为private)

  1. //代码1:内部类对外部类可见 
  2. class Outer{ 
  3.     //创建私有内部类对象 
  4.     public Inner in=new Inner(); 
  5.     //私有内部类 
  6.     private class Inner{ 
  7.          ... 
  8.     } 

        (2) 在内部类中可以访问其外部类的所有域,即使是私有域。即外部类对内部类可见。 例如

  1. //代码2:外部类对内部类可见 
  2. //(内部类可以访问外部类的所有成员变量和方法) 
  3. class Outer{ 
  4.     //外部类私有数据域 
  5.     private int data=0; 
  6.     //内部类 
  7.     class Inner{ 
  8.         void print(){ 
  9.             //内部类访问外部私有数据域 
  10.             System.out.println(data); 
  11.         } 
  12.     } 
  13. }  

        总结一下编译器对类中内部类做的手脚吧: (1)  在内部类中偷偷摸摸的创建了包可见构造器,从而使外部类获得了创建权限。 (2)  在外部类中偷偷摸摸的创建了访问私有变量的静态方法,从而 使 内部类获得了访问权限。 这样,类中定义的内部类无论私有,公有,静态都可以被包围它的外部类所访问。   2、静态内部类  ——  在方法间定义的内部类,静态     内部类也有静态的区别,这就是静态内部类,我们来看看代码:

  1. package hr.test; 
  2. //代码3:静态内部类对外部变量的引用 
  3. public class Outer{ 
  4.     private static int i=0; 
  5.     //创建静态内部类对象 
  6.     public Inner in=new Inner(); 
  7.     //静态内部类 
  8.     private static class Inner{ 
  9.         public void print(){ 
  10.             System.out.println(i);   //如果i不是静态变量,这里将无法通过编译 
  11.         } 
  12.     }  

    静态内部类和私有内部类最大的区别在于,静态内部类中无法引用到其外围类的非静态成员。

   是说静态内部类无法得到其外围类对象的引用,那么自然也就无法访问外围类的非静态成员了。 因此,静态内部类只能访问其外围类的静态成员,除此之外与非静态内部类没有任何区别。   3、局部内部类 —— 在方法中定义的内部类       方法内部类也有两个特点       (1)   方法中的内部类没有访问修饰符, 即方法内部类对包围它的方法之外的任何东西都不可见。       (2)   方法内部类只能够访问该方法中的局部变量,所以也叫局部内部类。而且这些局部变量一定要是final修饰的常量。 例如

  1. class Outter{ 
  2.     public void outMethod(){ 
  3.         final int beep=0; 
  4.         class Inner{ 
  5.             //使用beep 
  6.         } 
  7.         Inner in=new Inner(); 
  8.     } 
  9. }  

  内部类的特点总结   (1)  在方法间定义的非静态内部类:           外围类和内部类可互相访问自己的私有成员。          内部类中不能定义静态成员变量。

(2) 在方法间定义的静态内部类:          只能访问外部类的静态成员。   (3) 在方法中定义的局部内部类:          该内部类没有任何的访问控制权限          外围类看不见方法中的局部内部类的,但是局部内部类可以访问外围类的任何成员。          方法体中可以访问局部内部类,但是访问语句必须在定义局部内部类之后。          局部内部类只能访问方法体中的常量,即用final修饰的成员。

(4) 在方法中定义的匿名内部类:          没有构造器,取而代之的是将构造器参数传递给超类构造器。

继续阅读