Java 面向对象概述原理: 多态、Object类,转型(8)

Java 面向对象概述原理: 多态、Object类,转型(8)

 

http://docs.oracle.com/javase/tutorial/java/IandI/override.html

Java 面向对象概述原理:

 

Java中多态性的体现、前提、好处、弊端、应用:

 1 1,多态的体现:
 2     父类的引用指向了自己的子类对象。
 3     父类的引用也可以接收自己的子类对象。
 4 2,多态的前提:
 5     必须是类与类之间有关系。要么继承,要么实现。
 6     通常还有一个前提:存在覆盖。
 7 
 8 3,多态的好处:
 9     多态的出现大大的提高程序的扩展性。
10 
11 4,多态的弊端:
12     提高了扩展性,但是只能使用父类的引用访问父类中的成员。
13 
14 5,多态的应用
  6,多态的出现代码中的特点(多态使用的注意事项)
  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 
 52 
 53 class DuoTaiDemo 
 54 {
 55     public static void main(String[] args) 
 56     {
 57         //Cat c = new Cat();
 58         //c.eat();
 59 
 60         //Dog d = new Dog();
 61         //d.eat();
 62         //Cat c = new Cat();
 63         /*
 64         Cat c1 = new Cat();
 65         function(c1);
 66 
 67         function(new Dog());
 68         function(new Pig());
 69         */
 70 
 71         //Animal c = new Cat();
 72         //c.eat();
 73 
 74         
 75         function(new Cat());
 76         function(new Dog());
 77         function(new Pig());
 78         
 79 
 80         
 81     }
 82     public static void function(Animal a)//Animal a = new Cat();
 83     {
 84         a.eat();
 85         //a.catchMouse();
 86     }
 87     /*
 88     public static void function(Cat c)//
 89     {
 90         c.eat();
 91     }
 92     public static void function(Dog d)
 93     {
 94         d.eat();
 95     }
 96 
 97     public static void function(Pig p)
 98     {
 99         p.eat();
100     }
101     */
102 
103 }

 

多态的转型:

两种类型的类型转换

  (1)向上类型转换(Upcast):将子类型转换为父类型。

  对于向上的类型转换,不需要显示指定,即不需要加上前面的小括号和父类类型名。

  (2)向下类型转换(Downcast):将父类型转换为子类型。

  对于向下的类型转换,必须要显式指定,即必须要使用强制类型转换

 1 多态示例代码
 2 
 3 public class PolyTest
 4 {
 5     public static void main(String[] args)
 6     {
 7         
 8         //向上类型转换
 9         Cat cat = new Cat();
10         Animal animal = cat;
11         animal.sing();
12 
13                 
14         //向下类型转换
15         Animal a = new Cat();
16         Cat c = (Cat)a;
17         c.sing();
18         c.eat();
19 
20 
21         //编译错误
22         //用父类引用调用父类不存在的方法
23         //Animal a1 = new Cat();
24         //a1.eat();
25         
26         //编译错误
27         //向下类型转换时只能转向指向的对象类型        
28         //Animal a2 = new Cat();
29         //Cat c2 = (Dog)a2;
30         
31 
32 
33     }
34 }
35 class Animal
36 {
37     public void sing()
38     {
39         System.out.println("Animal is singing!");
40     }
41 }
42 class Dog extends Animal
43 {
44     public void sing()
45     {
46         System.out.println("Dog is singing!");
47     }
48 }
49 class Cat extends Animal
50 {
51     public void sing()
52     {
53         System.out.println("Cat is singing!");
54     }
55     public void eat()
56     {
57         System.out.println("Cat is eating!");
58     }
59 }

 

  1 第二个问题:如何使用子类特有方法。
  2 */
  3 
  4 /*
  5 动物,
  6 猫,狗。
  7 */
  8 
  9 class Cat extends Animal
 10 {
 11     public void eat()
 12     {
 13         System.out.println("吃鱼");
 14     }
 15     public void catchMouse()
 16     {
 17         System.out.println("抓老鼠");
 18     }
 19 }
 20 
 21 
 22 class Dog extends Animal
 23 {
 24     public void eat()
 25     {
 26         System.out.println("吃骨头");
 27     }
 28     public void kanJia()
 29     {
 30         System.out.println("看家");
 31     }
 32 }
 33 
 34 
 35 class Pig extends Animal
 36 {
 37     public void eat()
 38     {
 39         System.out.println("饲料");
 40     }
 41     public void gongDi()
 42     {
 43         System.out.println("拱地");
 44     }
 45 }
 46 
 47 //-----------------------------------------
 48 
 49 
 50 class DuoTaiDemo2 
 51 {
 52     public static void main(String[] args) 
 53     {
 54         //Animal a = new Cat();//类型提升。 向上转型。
 55         //a.eat();
 56 
 57         //如果想要调用猫的特有方法时,如何操作?
 58         //强制将父类的引用。转成子类类型。向下转型。
 59         ///Cat c = (Cat)a;
 60         //c.catchMouse();
 61         //千万不要出现这样的操作,就是将父类对象转成子类类型。
 62         //我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
 63         //多态自始至终都是子类对象在做着变化。
 64 //        Animal a = new Animal();
 65 //        Cat c = (Cat)a;
 66         
 67 
 68         /*
 69         毕姥爷 x = new 毕老师();
 70 
 71         x.讲课();
 72 
 73         毕老师 y = (毕老师)x;
 74 
 75 
 76         y.看电影();
 77         */
 78         function(new Dog());
 79         function(new Cat());
 80 
 81 
 82     }
 83     public static void function(Animal a)//Animal a = new Cat();
 84     {
 85         a.eat();
 86         /*
 87         if(a instanceof Animal)
 88         {
 89             System.out.println("haha");
 90         }
 91         else 
 92         */
 93         if(a instanceof Cat)
 94         {
 95             Cat c = (Cat)a;
 96             c.catchMouse();
 97         }
 98         else if(a instanceof Dog)
 99         {
100             Dog c = (Dog)a;
101             c.kanJia();
102         }
103 
104 
105         /*
106         instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)  
107         */
108     
109     }
110     
111 
112 
113 }
 1 /*
 2 基础班学生:
 3     学习,睡觉。
 4 高级班学生:
 5     学习,睡觉。
 6 
 7 可以将这两类事物进行抽取。
 8 
 9 */
10 
11 abstract class Student
12 {
13     public abstract void study();
14     public void sleep()
15     {
16         System.out.println("躺着睡");
17     }
18 }
19 
20 class DoStudent
21 {
22     
23     public void doSome(Student stu)
24     {
25         stu.study();
26         stu.sleep();
27     }
28     
29 }
30 
31 class BaseStudent extends Student
32 {
33     public void study()
34     {
35         System.out.println("base study");
36     }
37     public void sleep()
38     {
39          System.out.println("坐着睡");
40     }
41 }
42 
43 class AdvStudent extends Student
44 {
45     public void study()
46     {
47         System.out.println(" adv study");
48     }
49 }
50 
51 
52 
53 
54 class  DuoTaiDemo3
55 {
56     public static void main(String[] args) 
57     {
58 
59         DoStudent ds = new DoStudent();
60         ds.doSome(new BaseStudent());
61         ds.doSome(new AdvStudent());
62 
63         
64 //        BaseStudent bs = new BaseStudent();
65 //        bs.study();
66 //        bs.sleep();
67 //        AdvStudent as = new AdvStudent();
68 //        as.study();
69 //        as.sleep();
70     }
71 
72 }

 

 1 /*
 2 在多态中成员函数的特点:
 3 在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
 4 在运行时期:参阅对象所属的类中是否有调用的方法。
 5 简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
 6 
 7 
 8 在多态中,成员变量的特点:
 9 无论编译和运行,都参考左边(引用型变量所属的类)。
10 
11 
12 在多态中,静态成员函数的特点:
13 无论编译和运行,都参考做左边。
14 
15 
16 */

 

 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         
41 //        Fu f = new Zi();
42 //
43 //        System.out.println(f.num);
44 //
45 //        Zi z = new Zi();
46 //        System.out.println(z.num);
47 
48         //f.method1();
49         //f.method2();
50         //f.method3();
51 
52         Fu f = new Zi();
53         System.out.println(f.num);
54         f.method4();
55 
56         Zi z = new Zi();
57         z.method4();
58 
59     
60         
61 
62 
63 
64 //        Zi z = new Zi();
65 //        z.method1();
66 //        z.method2();
67 //        z.method3();
68     }
69 }    

 

 1 /*
 2 需求:
 3 电脑运行实例,
 4 电脑运行基于主板。
 5 */
 6 
 7 
 8 interface PCI
 9 {
10     public void open();
11     public void close();
12 }
13 
14 class MainBoard
15 {
16     public void run()
17     {
18         System.out.println("mainboard run ");
19     }
20     public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。
21     {
22         if(p!=null)
23         {
24             p.open();
25             p.close();
26             
27         }
28     }
29 }
30 
31 
32 class NetCard implements PCI
33 {
34     public void open()
35     {
36         System.out.println("netcard open");
37     }
38     public void close()
39     {
40         System.out.println("netcard close");
41         method();
42     }
43     
44 }
45 class SoundCard implements PCI
46 {
47     public void open()
48     {
49         System.out.println("SoundCard open");
50     }
51     public void close()
52     {
53         System.out.println("SoundCard close");
54     }
55 }
56 /*
57 class MainBoard
58 {
59     public void run()
60     {
61         System.out.println("mainboard run");
62     }
63     public void useNetCard(NetCard c)
64     {
65         c.open();
66         c.close();
67     }
68 }
69 
70 class NetCard
71 {
72     public void open()
73     {
74         System.out.println("netcard open");
75     }
76     public void close()
77     {
78         System.out.println("netcard close");
79     }
80 }
81 */
82 
83 class DuoTaiDemo5 
84 {
85     public static void main(String[] args) 
86     {
87         MainBoard mb = new MainBoard();
88         mb.run();
89         mb.usePCI(null);
90         mb.usePCI(new NetCard());
91         mb.usePCI(new SoundCard());
92         
93     }
94 }

 

参考博客:

http://www.cnblogs.com/mengdd/archive/2012/12/25/2832288.html

http://www.cnblogs.com/jack204/archive/2012/10/29/2745150.html

多态的概念:

  •   多态==晚绑定
  •   不要把函数重载理解为多态。因为多态是一种运行期的行为,不是编译期的行为。
  •   多态:父类型的引用可以指向子类型的对象。比如 Parent p = new Child(); 
  •   当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的该同名方法。
  •   
  •   (注意此处,静态static方法属于特殊情况,静态方法只能继承,不能重写Override,如果子类中定义了同名同形式的静态方法,它对父类方法只起到隐藏的作用。调用的时候用谁的引用,则调用谁的版本。)

  如果想要调用子类中有而父类中没有的方法,需要进行强制类型转换,如上面的例子中,将p转换为子类Child类型的引用。

  因为当用父类的引用指向子类的对象,用父类引用调用方法时,找不到父类中不存在的方法。这时候需要进行向下的类型转换,将父类引用转换为子类引用。     

  1 /*
  2 多态:可以理解为事物存在的多种体现形态。
  3 
  4 人:男人,女人
  5 
  6 动物:猫,狗。
  7 
  8 猫 x = new 猫();
  9 
 10 动物 x = new 猫();
 11 
 12 1,多态的体现
 13     父类的引用指向了自己的子类对象。
 14     父类的引用也可以接收自己的子类对象。
 15 2,多态的前提
 16     必须是类与类之间有关系。要么继承,要么实现。
 17     通常还有一个前提:存在覆盖。
 18 
 19 3,多态的好处
 20     多态的出现大大的提高程序的扩展性。
 21 
 22 4,多态的弊端:
 23     提高了扩展性,但是只能使用父类的引用访问父类中的成员。
 24 
 25 5,多态的应用
 26 
 27 
 28 
 29 */
 30 
 31 /*
 32 动物,
 33 猫,狗。
 34 */
 35 
 36 abstract class Animal
 37 {
 38     abstract void eat();
 39 
 40 }
 41 
 42 class Cat extends Animal
 43 {
 44     public void eat()
 45     {
 46         System.out.println("吃鱼");
 47     }
 48     public void catchMouse()
 49     {
 50         System.out.println("抓老鼠");
 51     }
 52 }
 53 
 54 
 55 class Dog extends Animal
 56 {
 57     public void eat()
 58     {
 59         System.out.println("吃骨头");
 60     }
 61     public void kanJia()
 62     {
 63         System.out.println("看家");
 64     }
 65 }
 66 
 67 
 68 class Pig extends Animal
 69 {
 70     public void eat()
 71     {
 72         System.out.println("饲料");
 73     }
 74     public void gongDi()
 75     {
 76         System.out.println("拱地");
 77     }
 78 }
 79 
 80 //-----------------------------------------
 81 
 82 
 83 class DuoTaiDemo 
 84 {
 85     public static void main(String[] args) 
 86     {
 87         //Cat c = new Cat();
 88         //c.eat();
 89 
 90         //Dog d = new Dog();
 91         //d.eat();
 92         //Cat c = new Cat();
 93         /*
 94         Cat c1 = new Cat();
 95         function(c1);
 96 
 97         function(new Dog());
 98         function(new Pig());
 99         */
100 
101         //Animal c = new Cat();
102         //c.eat();
103 
104         
105         function(new Cat());
106         function(new Dog());
107         function(new Pig());
108         
109 
110         
111     }
112     public static void function(Animal a)//Animal a = new Cat();
113     {
114         a.eat();
115         //a.catchMouse();
116     }
117     /*
118     public static void function(Cat c)//
119     {
120         c.eat();
121     }
122     public static void function(Dog d)
123     {
124         d.eat();
125     }
126 
127     public static void function(Pig p)
128     {
129         p.eat();
130     }
131     */
132 
133 }

 

 

 

 

 

什么是多态:

    1. 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
    2. 多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
    3. 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
    4. 多态的作用:消除类型之间的耦合关系。
    5. 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

多态存在的三个必要条件,要求大家做梦时都能背出来!

  • 多态存在的三个必要条件
  • 一、要有继承;
  • 二、要有重写;
  • 三、父类引用指向子类对象。

 

多态的好处

1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

Java中的多态:

  1 abstract class 动物
  2 {
  3     abstract void eat();
  4 }
  5 
  6 class Dog extends 动物
  7 {
  8     public void eat()
  9     {
 10         //骨头;
 11     }
 12 }
 13 
 14 classextends 动物
 15 {
 16     public void eat()
 17     {
 18         //吃鱼;
 19     }
 20 }
 21 
 22 classextends 动物
 23 {
 24     public void eat()
 25     {
 26         //饲料;
 27     }
 28 }
 29 
 30 class Demo
 31 {
 32     public void method(动物 x)//new Dog(); new 猫();
 33     {
 34         x.eat();
 35     }
 36     /*
 37     public void  method(猫 x)
 38     {
 39         x.eat();
 40     }
 41     public void  method(Dog x)
 42     {
 43         x.eat();
 44     }
 45     public void  method(猪 x)
 46     {
 47         x.eat();
 48     }
 49     */
 50 }
 51 
 52 class Main
 53 {
 54     public static void main(String[] args)
 55     {
 56         Demo d = new Demo();
 57         d.method(new Dog());
 58         d.method(new 猫());
 59     }
 60 }
 61 
 62 
 63 
 64 动物 x = new 猫();
 65 //猫 x = new 猫();
 66 
 67 一。表现:
 68 父类或者接口的引用指向了或者接收了自己的子类对象。
 69 
 70 二。前提:
 71 1,类与类之间要有关系。继承,实现。
 72 2,通常都会有覆盖。
 73 
 74 三。好处:
 75 预先定义的程序可以运行后期程序的内容。
 76 增强了程序的扩展性。
 77 
 78 四。弊端:
 79 虽然可以预先使用,但是只能访问父类中已有的功能,运行的是后期子类的功能内容。
 80 不能预先使用子类中定义的特有功能。
 81 
 82 五。多态的注意事项:
 83 在代码中。
 84 对于成员函数:Fu f = new Zi(); f.method();
 85 编译时期:看左边。
 86 运行时期:看右边。
 87 因为成员函数有一个覆盖操作。
 88     毕姥爷和毕老师的故事。
 89 
 90     
 91 对于非私有的实例变量,
 92 静态变量,静态方法。
 93 
 94 编译和运行都看左边。
 95 
 96 老师要求记住结论。有空闲时间,就想想为什么?
 97 
 98 六。转型。
 99 子类对象被父类引用:子类对象在向上转型。
100 将指向子类对象的父类应用转换成子类类型引用:向下转型。
101 
102 毕姥爷和毕老师的故事。
103 class 毕姥爷
104 {}
105 
106 class 毕老师 extends 毕姥爷
107 {}
108 
109 毕姥爷 ly = new 毕老师();//毕老师向上转型为了毕姥爷。向上转型
110 
111 毕老师 ls = (毕老师)ly; //将代表毕老师对象的父类引用ly强制转换成了毕老师类型。向下转型。
112 
113 
114 
115 七。应用
116 电脑使用。主板运行。
117 
118 class MainBoard
119 {
120     public void run()
121     {
122         //主板运行;
123     }
124     public void usePCI(PCI p)//PCI p = new NetCard();
125     {
126         if(p!=null)
127         {
128             p.open();
129             p.close();
130         }
131     }
132 }
133 
134 
135 //为了提高主板功能的扩展性。
136 //定义了规则。让后期的出现的功能板块,只要覆盖该规则,就可以被这个主板使用。
137 interface PCI
138 {
139     void open();
140     void close();
141 }
142 
143 
144 
145 
146 class MainDemo
147 {
148     public static void main(String[] args)
149     {
150         MainBoard mb = new MainBoard();
151         mb.run();
152         mb.usePCI(null);
153         mb.usePCI(new NetCard());
154 
155 
156 
157     }
158 }
159 
160 
161 class NetCard implements PCI
162 {
163     public void open(){}
164     public void close(){}
165 }
166 
167 
168 Object:是java中所有对象的直接或者间接的父类。
169     它里面的方法都所有对象都具备的。
170     常见方法:
171     boolean equals(Object obj):用于比较两个对象是否相同。
172     String toString(): 获取对象的字符串表现形式 类名@哈希值  
173         getClass().getName()+"@"+Integer.toHexString(hashCode());
174     Class getClass():获取正在运行的对象所属的字节码文件的对象。也就是说如果Demo d = new Demo();
175                 d.getClass():获取的就是d执行的对象所属的字节码文件Demo.class对象。
176     
177     通常在自定义对象时,因为对象中都有自己特有的描述,
178     所以都会建立对象自身的特有比较方法,或者字符串表现形式。
179     也就是说,会覆盖Object中的方法。
180 
181 
182 /*
183 Demo d1 = new Demo();
184 Demo d2 = new Demo();
185 d1.getClass() ==  d2.getClass();
186 */
187 
188 
189 class Demo //extends Object
190 {
191     public String toString()
192     {
193         this.getClass().getName()+"#"+Integer.toHexString(this.hashCode());
194     }
195 }
196     
197 
198 class Fu
199 {
200     void show(){System.out.println("fu show");}
201 }
202 class Zi extends Fu
203 {
204     void function()
205     {
206         super.show();
207         //this.show();
208     }
209     void show(){System.out.println("zi show");}
210 }
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 /*
232 
233 class Computer
234 {
235     private MainBoard mb;
236 
237     Computer()
238     {
239         mb = new MainBoard();
240     }
241     public void play()
242     {
243         mb.run();
244     }
245 }
246 */

 

转载于:https://www.cnblogs.com/itcqx/p/5541670.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值