黑马程序员------继承(三)

1.1 多态:可以理解为某一类事物存在的多种体现形态

人:男人,女人

动物:猫,狗。

猫 x = new 猫();

动物 x = new 猫();

1,体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。

3,好处
多态的出现大大的提高程序的扩展性。

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

示例1:

 1 /*
 2 动物,
 3 猫,狗。
 4 */
 5 
 6 abstract class Animal
 7 {
 8     abstract void eat();
 9 
10 }
11 
12 class Cat extends Animal
13 {
14     public void eat()
15     {
16         System.out.println("吃鱼");
17     }
18     public void catchMouse()
19     {
20         System.out.println("抓老鼠");
21     }
22 }
23 
24 
25 class Dog extends Animal
26 {
27     public void eat()
28     {
29         System.out.println("吃骨头");
30     }
31     public void kanJia()
32     {
33         System.out.println("看家");
34     }
35 }
36 
37 
38 class Pig extends Animal
39 {
40     public void eat()
41     {
42         System.out.println("饲料");
43     }
44     public void gongDi()
45     {
46         System.out.println("拱地");
47     }
48 }
49 
50 
51 class DuoTaiDemo 
52 {
53     public static void main(String[] args) 
54     {
55         //Cat c = new Cat();
56         //c.eat();
57 
58         //Dog d = new Dog();
59         //d.eat();
60         //Cat c = new Cat();
61         /*
62         Cat c1 = new Cat();
63         function(c1);
64 
65         function(new Dog());
66         function(new Pig());
67         */
68 
69         //Animal c = new Cat();
70         //c.eat();
71 
72         
73         function(new Cat());
74         function(new Dog());
75         function(new Pig());
76         
77 
78         
79     }
80     public static void function(Animal a)//Animal a = new Cat();
81     {
82         a.eat();
83         //a.catchMouse();
84     }
85     
86 }

 

1.2 如何使用子类特有方法呢?

     向上转型或者向下转型(示例2)

示例2:

 1 class Cat extends Animal
 2 {
 3     public void eat()
 4     {
 5         System.out.println("吃鱼");
 6     }
 7     public void catchMouse()
 8     {
 9         System.out.println("抓老鼠");
10     }
11 }
12 
13 
14 class Dog extends Animal
15 {
16     public void eat()
17     {
18         System.out.println("吃骨头");
19     }
20     public void kanJia()
21     {
22         System.out.println("看家");
23     }
24 }
25 
26 
27 class Pig extends Animal
28 {
29     public void eat()
30     {
31         System.out.println("饲料");
32     }
33     public void gongDi()
34     {
35         System.out.println("拱地");
36     }
37 }
38 
39 
40 class DuoTaiDemo2 
41 {
42     public static void main(String[] args) 
43     {
44         //Animal a = new Cat();//类型提升。 向上转型。
45         //a.eat();
46 
47         //如果想要调用猫的特有方法时,如何操作?
48         //强制将父类的引用。转成子类类型。向下转型。
49         ///Cat c = (Cat)a;
50         //c.catchMouse();
51         //千万不要出现这样的操作,就是将父类对象转成子类类型。
52         //我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
53         //多态自始至终都是子类对象在做着变化。
54                //Animal a = new Animal();
55               //Cat c = (Cat)a;
56         
57 
58     
59         function(new Dog());
60         function(new Cat());
61 
62 
63     }
64     public static void function(Animal a)//Animal a = new Cat();
65     {
66         a.eat();
67         /*
68         if(a instanceof Animal)
69         {
70             System.out.println("haha");
71         }
72         else 
73         */
74         if(a instanceof Cat)
75         {
76             Cat c = (Cat)a;
77             c.catchMouse();
78         }
79         else if(a instanceof Dog)
80         {
81             Dog c = (Dog)a;
82             c.kanJia();
83         }
84 
85     }
86 
87 }
88  

 

PS:

instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型) 


1.3 多态在成员变量和成员函数中的特点:

在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。


在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。


在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边。

示例3

 1 class Fu
 2 {
 3     static int num = 5;
 4     void method1()
 5     {
 6         System.out.println("fu method_1");
 7     }
 8     void method2()
 9     {
10         System.out.println("fu method_2");
11     }
12     static void method4()
13     {
14         System.out.println("fu method_4");
15     }
16 }
17 
18 
19 class Zi extends Fu
20 {
21     static int num = 8;
22     void method1()
23     {
24         System.out.println("zi method_1");
25     }
26     void method3()
27     {
28         System.out.println("zi method_3");
29     }
30 
31     static void method4()
32     {
33         System.out.println("zi method_4");
34     }
35 }
36 class  DuoTaiDemo4
37 {
38     public static void main(String[] args) 
39     {
40         //Fu f = new Zi();
41         //System.out.println(f.num);
42         //Zi z = new Zi();
43         //System.out.println(z.num);
44 
45         //f.method1();
46         //f.method2();
47         //f.method3();
48 
49         Fu f = new Zi();
50         System.out.println(f.num);
51         f.method4();
52 
53         Zi z = new Zi();
54         z.method4();
55         }
56 }

 

 

1.4 上帝之父 Object类

Object:是所有对象的直接后者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能。

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

如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖

 

1.5 内部类(示例4)

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

内部类的访问规则:
1,内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2,外部类要访问内部类,必须建立内部类对象。

访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式
外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();

2,当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();

在外部其他类中,如何直接访问static内部类的静态成员呢?
uter.Inner.function();

注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的。

 

当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事务在使用外部事物的内容。

示例4:

 1 class Body
 2 {
 3     private class XinZang
 4     {
 5 
 6     }
 7 
 8     public void show()
 9     {
10         new XinZang().
11     }
12     
13 }
14 
15 
16 class Outer
17 {
18     private static  int x = 3;
19 
20     
21     static class Inner//静态内部类
22     {
23         static void function()
24         {
25             System.out.println("innner :"+x);
26         }
27     }
28 
29     static class Inner2
30     {
31         void show()
32         {
33             System.out.println("inner2 show");
34         }
35     }
36 
37     public static void method()
38     {
39         //Inner.function();
40         new Inner2().show();
41     }
42 
43 }
44 
45 
46 class  InnerClassDemo2
47 {
48     public static void main(String[] args) 
49     {
50         Outer.method();
51         //Outer.Inner.function();
52         //new Outer.Inner().function();
53         //直接访问内部类中的成员。
54                //Outer.Inner in = new Outer().new Inner();
55               //in.function();
56     }
57 }

 

1.5.2内部类注意事项(示例5):

内部类定义在局部时,
1,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。

示例5:

 1 class Outer
 2 {
 3     int x = 3;
 4 
 5     void method(final int a)
 6     {
 7         final int y = 4;
 8         class Inner
 9         {
10             void function()
11             {
12                 System.out.println(y);
13             }
14         }
15     
16         new Inner().function();
17         
18     }
19 }
20 
21 
22 class  InnerClassDemo3
23 {
24     public static void main(String[] args) 
25     {
26         Outer out = new Outer();
27         out.method(7);
28         out.method(8);
29     }
30 
31 }

 

 

1.5.3 匿名内部类(示例6):

1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。

示例6:

 1 abstract class AbsDemo
 2 {
 3     abstract void show();
 4     
 5 }
 6 
 7 
 8 class Outer
 9 {
10     int x = 3;
11 
12     /*
13     class Inner extends AbsDemo
14     {
15         int num = 90;
16         void show()
17         {
18             System.out.println("show :"+num);
19         }
20         void abc()
21         {
22             System.out.println("hehe");
23         }
24     }
25     */
26 
27     public void function()
28     {
29         AbsDemo d = new AbsDemo()
30         {
31             int num = 9;
32             void show()
33             {
34                 System.out.println("num==="+num);
35             }
36             void abc()
37             {
38                 System.out.println("haha");
39             }
40         };
41 
42         d.show();
43         //d.abc();//编译失败;
44 
45     }
46 }
47 
48 
49 
50 class InnerClassDemo4 
51 {
52     public static void main(String[] args) 
53     {
54         new Outer().function();
55     }
56 }

 

posted on 2015-06-13 17:17  若诺  阅读(145)  评论(0编辑  收藏  举报