Java笔记(07):面向对象--多态

1、final关键字

 1 /*
 2     final可以修饰类,方法,变量
 3
 4     特点:
 5         final可以修饰类,该类不能被继承。
 6         final可以修饰方法,该方法不能被重写。(覆盖,复写)
 7         final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。
 8
 9     常量:
10         A:字面值常量
11             "hello",10,true
12         B:自定义常量
13             final int x = 10;
14 */
15
16 //final class Fu //无法从最终Fu进行继承
17
18 class Fu {
19     public int num = 10;
20     public final int num2 = 20;
21
22     /*
23     public final void show() {
24
25     }
26     */
27 }
28
29 class Zi extends Fu {
30     // Zi中的show()无法覆盖Fu中的show()
31     public void show() {
32         num = 100;
33         System.out.println(num);
34
35         //无法为最终变量num2分配值
36         //num2 = 200;
37         System.out.println(num2);
38     }
39 }
40
41 class FinalDemo {
42     public static void main(String[] args) {
43         Zi z = new Zi();
44         z.show();//100 20
45     }
46 }

2、final修饰局部变量

 1 /*
 2     面试题:final修饰局部变量的问题
 3         基本类型:基本类型的值不能发生改变。
 4         引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。
 5 */
 6 class Student {
 7     int age = 10;
 8 }
 9
10 class FinalTest {
11     public static void main(String[] args) {
12         //局部变量是基本数据类型
13         int x = 10;
14         x = 100;
15         System.out.println(x);
16         final int y = 10;
17         //无法为最终变量y分配值
18         //y = 100;
19         System.out.println(y);
20         System.out.println("--------------");
21
22         //局部变量是引用数据类型
23         Student s = new Student();
24         System.out.println(s.age);
25         s.age = 100;
26         System.out.println(s.age);
27         System.out.println("--------------");
28
29         final Student ss = new Student();
30         System.out.println(ss.age);
31         ss.age = 100;
32         System.out.println(ss.age);
33
34         //重新分配内存空间
35         //无法为最终变量ss分配值
36         ss = new Student();
37     }
38 }

3、final修饰变量的时机

 1 /*
 2     final修饰变量的初始化时机
 3         A:被final修饰的变量只能赋值一次。
 4         B:在构造方法完毕前。(非静态的常量)
 5 */
 6 class Demo {
 7     //int num = 10;
 8     //final int num2 = 20;
 9
10     int num;
11     final int num2;
12
13     {
14         //num2 = 10;
15     }
16
17     public Demo() {
18         num = 100;
19         //无法为最终变量num2分配值
20         num2 = 200;
21     }
22 }
23
24 class FinalTest2 {
25     public static void main(String[] args) {
26         Demo d = new Demo();
27         System.out.println(d.num);
28         System.out.println(d.num2);
29     }
30 }

4、继承的代码体现

 1 /*
 2     继承的代码体现
 3
 4     由于继承中方法有一个现象:方法重写。
 5     所以,父类的功能,就会被子类给覆盖调。
 6     有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。
 7     这个时候,针对这种情况,Java就提供了一个关键字:final
 8
 9     final:最终的意思。常见的是它可以修饰类,方法,变量。
10 */
11 class Fu {
12     public final void show() {
13         System.out.println("这里是绝密资源,任何人都不能修改");
14     }
15 }
16
17 class Zi extends Fu {
18     // Zi中的show()无法覆盖Fu中的show()
19     public void show() {
20         System.out.println("这是一堆垃圾");
21     }
22 }
23
24 class ZiDemo {
25     public static void main(String[] args) {
26         Zi z = new Zi();
27         z.show();
28     }
29 }

5、多态

 1 /*
 2     多态:同一个对象(事物),在不同时刻体现出来的不同状态。
 3     举例:
 4         猫是猫,猫是动物。
 5         水(液体,固体,气态)。
 6
 7     多态的前提:
 8         A:要有继承关系。
 9         B:要有方法重写。
10             其实没有也是可以的,但是如果没有这个就没有意义。
11                 动物 d = new 猫();
12                 d.show();
13                 动物 d = new 狗();
14                 d.show();
15         C:要有父类引用指向子类对象。
16             父 f =  new 子();
17
18     用代码体现一下多态。
19
20     多态中的成员访问特点:
21         A:成员变量
22             编译看左边,运行看左边。
23         B:构造方法
24             创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
25         C:成员方法
26             编译看左边,运行看右边。
27         D:静态方法
28             编译看左边,运行看左边。
29             (静态和类相关,算不上重写,所以,访问还是左边的)
30
31         由于成员方法存在方法重写,所以它运行看右边。
32 */
33 class Fu {
34     public int num = 100;
35
36     public void show() {
37         System.out.println("show Fu");
38     }
39
40     public static void function() {
41         System.out.println("function Fu");
42     }
43 }
44
45 class Zi extends Fu {
46     public int num = 1000;
47     public int num2 = 200;
48
49     public void show() {
50         System.out.println("show Zi");
51     }
52
53     public void method() {
54         System.out.println("method zi");
55     }
56
57     public static void function() {
58         System.out.println("function Zi");
59     }
60 }
61
62 class DuoTaiDemo {
63     public static void main(String[] args) {
64         //要有父类引用指向子类对象。
65         //父 f =  new 子();
66         Fu f = new Zi();
67         System.out.println(f.num);//100
68         //找不到符号
69         //System.out.println(f.num2);
70
71         f.show();//show Zi
72         //找不到符号
73         //f.method();
74         f.function();//function Fu
75     }
76 }

6、多态的好处

  1 /*
  2     多态的好处:
  3         A:提高了代码的维护性(继承保证)
  4         B:提高了代码的扩展性(由多态保证)
  5
  6     猫狗案例代码
  7 */
  8 class Animal {
  9     public void eat(){
 10         System.out.println("eat");
 11     }
 12
 13     public void sleep(){
 14         System.out.println("sleep");
 15     }
 16 }
 17
 18 class Dog extends Animal {
 19     public void eat(){
 20         System.out.println("狗吃肉");
 21     }
 22
 23     public void sleep(){
 24         System.out.println("狗站着睡觉");
 25     }
 26 }
 27
 28 class Cat extends Animal {
 29     public void eat() {
 30         System.out.println("猫吃鱼");
 31     }
 32
 33     public void sleep() {
 34         System.out.println("猫趴着睡觉");
 35     }
 36 }
 37
 38 class Pig extends Animal {
 39     public void eat() {
 40         System.out.println("猪吃白菜");
 41     }
 42
 43     public void sleep() {
 44         System.out.println("猪侧着睡");
 45     }
 46 }
 47
 48 //针对动物操作的工具类
 49 class AnimalTool {
 50     private AnimalTool(){}
 51
 52     /*
 53     //调用猫的功能
 54     public static void useCat(Cat c) {
 55         c.eat();
 56         c.sleep();
 57     }
 58
 59     //调用狗的功能
 60     public static void useDog(Dog d) {
 61         d.eat();
 62         d.sleep();
 63     }
 64
 65     //调用猪的功能
 66     public static void usePig(Pig p) {
 67         p.eat();
 68         p.sleep();
 69     }
 70     */
 71     public static void useAnimal(Animal a) {
 72         a.eat();
 73         a.sleep();
 74     }
 75
 76 }
 77
 78 class DuoTaiDemo2 {
 79     public static void main(String[] args) {
 80         //我喜欢猫,就养了一只
 81         Cat c = new Cat();
 82         c.eat();
 83         c.sleep();
 84
 85         //我很喜欢猫,所以,又养了一只
 86         Cat c2 = new Cat();
 87         c2.eat();
 88         c2.sleep();
 89
 90         //我特别喜欢猫,又养了一只
 91         Cat c3 = new Cat();
 92         c3.eat();
 93         c3.sleep();
 94         //...
 95         System.out.println("--------------");
 96         //问题来了,我养了很多只猫,每次创建对象是可以接受的
 97         //但是呢?调用方法,你不觉得很相似吗?仅仅是对象名不一样。
 98         //我们准备用方法改进
 99         //调用方式改进版本
100         //useCat(c);
101         //useCat(c2);
102         //useCat(c3);
103
104         //AnimalTool.useCat(c);
105         //AnimalTool.useCat(c2);
106         //AnimalTool.useCat(c3);
107
108         AnimalTool.useAnimal(c);
109         AnimalTool.useAnimal(c2);
110         AnimalTool.useAnimal(c3);
111         System.out.println("--------------");
112
113         //我喜欢狗
114         Dog d = new Dog();
115         Dog d2 = new Dog();
116         Dog d3 = new Dog();
117         //AnimalTool.useDog(d);
118         //AnimalTool.useDog(d2);
119         //AnimalTool.useDog(d3);
120         AnimalTool.useAnimal(d);
121         AnimalTool.useAnimal(d2);
122         AnimalTool.useAnimal(d3);
123         System.out.println("--------------");
124
125         //我喜欢宠物猪
126         //定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用
127         Pig p = new Pig();
128         Pig p2 = new Pig();
129         Pig p3 = new Pig();
130         //AnimalTool.usePig(p);
131         //AnimalTool.usePig(p2);
132         //AnimalTool.usePig(p3);
133         AnimalTool.useAnimal(p);
134         AnimalTool.useAnimal(p2);
135         AnimalTool.useAnimal(p3);
136         System.out.println("--------------");
137
138         //我喜欢宠物狼,老虎,豹子...
139         //定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用
140         //前面几个必须写,我是没有意见的
141         //但是,工具类每次都改,麻烦不
142         //我就想,你能不能不改了
143         //太简单:把所有的动物都写上。问题是名字是什么呢?到底哪些需要被加入呢?
144         //改用另一种解决方案。
145
146     }
147
148     /*
149     //调用猫的功能
150     public static void useCat(Cat c) {
151         c.eat();
152         c.sleep();
153     }
154
155     //调用狗的功能
156     public static void useDog(Dog d) {
157         d.eat();
158         d.sleep();
159     }
160     */
161 }

7、多态的弊端

 1 /*
 2     多态的弊端:
 3         不能使用子类的特有功能。
 4 */
 5 class Fu {
 6     public void show() {
 7         System.out.println("show fu");
 8     }
 9 }
10
11 class Zi extends Fu {
12     public void show() {
13         System.out.println("show zi");
14     }
15
16     public void method() {
17         System.out.println("method zi");
18     }
19
20 }
21
22 class DuoTaiDemo3 {
23     public static void main(String[] args) {
24         //测试
25         Fu f = new Zi();
26         f.show();
27         f.method();
28     }
29 }

8、多态的向上向下转型

 1 /*
 2     多态的弊端:
 3         不能使用子类的特有功能。
 4
 5     我就想使用子类的特有功能?行不行?
 6         行。
 7
 8     怎么用呢?
 9         A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
10         B:把父类的引用强制转换为子类的引用。(向下转型)
11
12     对象间的转型问题:
13         向上转型:
14             Fu f = new Zi();
15         向下转型:
16             Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
17 */
18 class Fu {
19     public void show() {
20         System.out.println("show fu");
21     }
22 }
23
24 class Zi extends Fu {
25     public void show() {
26         System.out.println("show zi");
27     }
28
29     public void method() {
30         System.out.println("method zi");
31     }
32
33 }
34
35 class DuoTaiDemo4 {
36     public static void main(String[] args) {
37         //测试
38         Fu f = new Zi();
39         f.show();
40         //f.method();
41
42         //创建子类对象
43         //Zi z = new Zi();
44         //z.show();
45         //z.method();
46
47         //你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
48         //如果可以,但是如下
49         Zi z = (Zi)f;
50         z.show();
51         z.method();
52     }
53 }

多态的内存图解:

多态的对象变化内存图解:

9、ClassCastException:类型转换异常

 1 /*
 2     ClassCastException:类型转换异常
 3     一般在多态的向下转型中容易出现
 4 */
 5 class Animal {
 6     public void eat(){}
 7 }
 8
 9 class Dog extends Animal {
10     public void eat() {}
11
12     public void lookDoor() {
13
14     }
15 }
16
17 class Cat extends Animal {
18     public void eat() {
19
20     }
21
22     public void playGame() {
23
24     }
25 }
26
27 class DuoTaiDemo5 {
28     public static void main(String[] args) {
29         //内存中的是狗
30         Animal a = new Dog();
31         Dog d = (Dog)a;
32
33         //内存中是猫
34         a = new Cat();
35         Cat c = (Cat)a;
36
37         //内存中是猫
38         Dog dd = (Dog)a; //ClassCastException
39     }
40 }

练习:猫狗案例

 1 /*
 2     多态练习:猫狗案例
 3 */
 4 class Animal {
 5     public void eat(){
 6         System.out.println("吃饭");
 7     }
 8 }
 9
10 class Dog extends Animal {
11     public void eat() {
12         System.out.println("狗吃肉");
13     }
14
15     public void lookDoor() {
16         System.out.println("狗看门");
17     }
18 }
19
20 class Cat extends Animal {
21     public void eat() {
22         System.out.println("猫吃鱼");
23     }
24
25     public void playGame() {
26         System.out.println("猫捉迷藏");
27     }
28 }
29
30 class DuoTaiTest {
31     public static void main(String[] args) {
32         //定义为狗
33         Animal a = new Dog();
34         a.eat();
35         System.out.println("--------------");
36         //还原成狗
37         Dog d = (Dog)a;
38         d.eat();
39         d.lookDoor();
40         System.out.println("--------------");
41         //变成猫
42         a = new Cat();
43         a.eat();
44         System.out.println("--------------");
45         //还原成猫
46         Cat c = (Cat)a;
47         c.eat();
48         c.playGame();
49         System.out.println("--------------");
50
51         //演示错误的内容
52         //Dog dd = new Animal();
53         //Dog ddd = new Cat();
54         //ClassCastException
55         //Dog dd = (Dog)a;
56     }
57 }    

练习:爱你

 1 /*
 2     看程序写结果:先判断有没有问题,如果没有,写出结果
 3
 4     多态的成员访问特点:
 5         方法:编译看左边,运行看右边。
 6
 7     继承的时候:
 8         子类中有和父类中一样的方法,叫重写。
 9         子类中没有父亲中出现过的方法,方法就被继承过来了。
10 */
11 class A {
12     public void show() {
13         show2();
14     }
15     public void show2() {
16         System.out.println("我");
17     }
18 }
19 class B extends A {
20     /*
21     public void show() {
22         show2();
23     }
24     */
25
26     public void show2() {
27         System.out.println("爱");
28     }
29 }
30 class C extends B {
31     public void show() {
32         super.show();
33     }
34     public void show2() {
35         System.out.println("你");
36     }
37 }
38 public class DuoTaiTest4 {
39     public static void main(String[] args) {
40         A a = new B();
41         a.show();//爱
42
43         B b = new C();
44         b.show();//你
45     }
46 }
时间: 2024-10-05 01:00:53

Java笔记(07):面向对象--多态的相关文章

java学习笔记之面向对象多态

面向对象三大特性之多态 一.多态的概念 多态是继封装,继承之后,面向对象的三大特性. 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的张三同学既是学生也是人,即出现两种形态. java作为面向对象的语言,同样可以描述一个事物的多种形态,java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口) 变量赋值. 父类的引用变量指向子类对象.多态的前提需要有继承关系或者是实现关系,否则没法完成多态.在使用

Java笔记之面向对象

/* 1. 面向对象概念(Java中一切皆对象) 1.1. 面向对象是相对面向过程而言的 1.2. 面向对象和面向过程都是一种思想 1.3. 面向过程 a. 强调的是功能行为,面向过程是一种思想    1.4. 面向对象 a. 将功能封装进对象,强调具备了功能的对象,    找到功能对应的事物,将功能封装进事物,以后    就操作这个事物就可以了,将复杂的问题简单化    将我们的角色由执行者转变为指挥者 1.5. 面向对象是基于面向过程的 1.6. example */ class NewDe

Java笔记(07):常见对象--StringBuffer、二分查找及排序算法

1.StringBuffer类的构造方法 1 package cn.itcast_01; 2 3 /* 4 * 线程安全(多线程讲解) 5 * 安全 -- 同步 -- 数据是安全的 6 * 不安全 -- 不同步 -- 效率高一些 7 * 安全和效率问题是永远困扰我们的问题. 8 * 安全:医院的网站,银行网站 9 * 效率:新闻网站,论坛之类的 10 * 11 * StringBuffer: 12 * 线程安全的可变字符串. 13 * 14 * StringBuffer和String的区别? 1

5.3-全栈Java笔记:面向对象特征(二)封装、多态

封装(encapsulation) 封装的作用和含义 我要看电视,只需要按一下开关和换台就可以了.有必要了解电视机内部的结构吗?有必要碰碰显像管吗?制造厂家为了方便我们使用电视,把复杂的内部细节全部封装起来,只给我们暴露简单的接口,比如:电源开关.具体怎么内部实现的,我们不需要操心. 需要让用户知道的暴露出来,不需要让用户了解的全部隐藏起来.这就是封装. 我们程序设计要追求"高内聚,低耦合". 高内聚就是类的内部数据操作细节自己完成,不允许外部干涉:低耦合:仅暴露少量的方法给外部使用,

5.1-全栈Java笔记:面向对象的特征(一)继承 | 上

JAVA面向对象进阶 本章重点针对面向对象的三大特征:继承.封装.多态,进行详细的讲解.很多概念对于初学者来说,更多的是先进行语法性质的了解,不要期望,通过本章学习就"搞透面向对象".本章只是面向对象的起点,后面所有的章节说白了都是面向对象这一章的应用. 老鸟建议 建议大家,学习本章,莫停留!学完以后,迅速开展后面的章节.可以说这么说,以后所有的编程都是"面向对象"的应用而已! 继承(extend) 继承的实现 继承让我们更加容易实现类的扩展. 比如,我们定义了人类

Java学习笔记<3>面向对象相关

面向对象的基本思想 从现实世界客观存在的事务出发来构造软件系统,并在系统的构造中尽可能运用人类的自然思维方式,如抽象.分类 继承.聚合.多态等. 类和对象的关系 对象中存储了类规定的数据类型,并且对象可以调用类的方法. java面向对象 <1>对象是java程序的核心,一切皆对象. <2>对象可以看成静态属性(成员变量)和动态属性(方法)的封装体. <3>类是创新同一类型对象的模版,定义了该类型对象应具有的成员变量及方法. 类的定义 成员变量可以用java语言的任何一种

java学习笔记之面向对象static,final关键字

java学习笔记之面向对象static,final关键字 一.static关键字 1.概述: static静态的,被static修饰的成员属于类,不属于单个对象,被所有对象所共享,存在静态区中,静态的成员优先于对象加载到内存中. 2.statc修饰成员的使用方式:(被static修饰的成员变量有默认值) /* 1.可以通过对象直接使用,不推荐使用 2.通过类名调用静态成员 类名.静态成员变量 类名.静态成员方法 */ 3.static的特点 /* 1.在同一个类中,静态成员只能访问静态成员,非静

5.2-全栈Java笔记:面向对象的特征(一)继承 | 下

上节我们聊到「Java面向对象的特征:继承」这节我们继续聊一下继承的应用. Object类 Object类基本特性 Object类是所有Java类的根基类,也就意味着所有的JAVA对象都拥有Object类的属性和方法.如果在类的声明中未使用extends关键字指明其父类,则默认继承Object类. [示例1]Object类 public class Person { ... } //等价于: public class Person extends   Object { ... } toStrin

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数、抽象类、虚析构函数、动态创建对象

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数.抽象类.虚析构函数.动态创建对象 一.纯虚函数 1.虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 2.如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 3.在基类中不能给出有意义的虚函数定义,这时可以把它声明成纯虚函数,把它的定义留给派生类来做 4.定义纯虚函数: class <类名> { virtual <类型> <函