1、多态的概念和前提(掌握)
1、概念-什么是多态(掌握)
对象在不同时刻表现出来的不同状态。
2、针对引用类型的理解
编译期间状态和运行期间状态不一样
比如
Person p = new Person();//第一行
p = new Man();//第二行
p = new Woman();//第三行
p在第二个代表的是男人,在第三行代表的是女人。
3、举例
水(水,冰,水蒸气)
狗:狗是狗,狗是动物,狗是宠物,狗是食物//该处强调谁是谁的一种
A:要有继承关系或实现关系
B:要有方法重写或实现关系
C:要有父类引用指向子类对象,或父接口引用指向子类对象
2、多态的成员特点(掌握)
1、成员变量
编译看左边,运行看左边。//就是因为变量不存在重写(掌握)
Fu fu = new Zi();
System.out.println(fu.name);//调用的是父类的name属性
2、成员方法
编译看等于号左边,运行看等于号右边。//因为方法存在重写(掌握)
Fu fu = new Zi();
fu.show();//调用的是子类的show()
3、产生以上现象的原因(掌握)
因为方法有重写,变量没有
总结一句话:方法运行看右边
注意:静态和面向对象没关系
classFu{
publicString name ="爸爸";
publicvoid say(){
System.out.println("我来自20世纪");
}
}
classZiextendsFu{
publicString name ="儿子";
@Override
publicvoid say(){
System.out.println("我来自21世纪");
}
}
publicclassTest01{
publicstaticvoid main(String[] args){
//父类引用指向子类对象,这就是多态
Fu fu =newZi();
/*
编译的时候查看 = 号左边的Fu类中是否包含name属性,如果包含,就编译通过,
运行的时候看 = 左边是Fu,所以输出爸爸。
总结:成员变量编译看左边,运行看左边
*/
System.out.println(fu.name);
/*
编译的时候查看 = 号左边的Fu类中是否包含say方法,如果包含,就编译通过,
运行的时候看 = 右边的对象,发现右边是子类对象,所以调用子类的方法。
总结:成员方法编译看左边,运行看右边
*/
fu.say();
}
}
3、多态的弊端(掌握)
父类引用不能直接使用子类对象的特有功能
如何解决这个问题?
答:向下转型 (就是强转)
格式 (子类)父类
4、多态的好处(了解)
增强了程序的扩展性和可维护性
扩展性:同一个方法可以接收不通类型的数据
可维护性:以前修改10行代码,现在只需要修改1行代码,减少了维护成本
5、基本类型 和 引用类型中类型转换问题(掌握)
1、基本类型:隐式转换(小到大),强制转换(大到小)。
隐式转换:
byte b = 1;int i = b;
强制转换:
int i = 1;byte b = (byte)i;
2、引用类型:向上转型(小到大),向下转型(大到小)。
向上转型 :子类引用赋值给父类引用
Zi zi = new Zi();Fu fu = zi;
向下转型 :父类引用赋值给子类引用
Fu fu = new Zi();
Zi zi = (Zi)fu;
3、引用类型转换过程中的问题
java.lang.ClassCastException :类型转换异常
该异常产生的原因:类型不匹配
一个父类的引用指向的是狗,要把这个父类的引用强制转换成猫,所以不行
Animal animal = new Dog();
Cat cat = (Cat)animal;//因为animal存储的是狗,强转成猫就会报错
5、抽象类和抽象方法(掌握)
由来
类里面封装的是相关的属性和行为,但是有些行为我们是不确定做什么的,这个时候我们就把这个方法用abstract修饰,当方法被这个关键字修饰以后,就不能有方法体了,并且这个类也必须被abstract修饰,这就是抽象类的由来
1、抽象方法
只有方法声明,没有方法体的方法称为抽象方法,该方法被abstract修饰
2、抽象类
如果一个类中含有抽象方法,这个类就可以被称为抽象类。该类也需要被abstract修饰
3、什么时候定义抽象类(掌握)
如果一个方法我们不确定他要做什么,就把这个方法定义成抽象的,那么这个类就必须被定义成抽象的
3、格式(掌握)
定义抽象类的格式
abstract class Animal{
abstract void eat();
public void run(){
System.out.println("我在跑步");
}
}
使用格式1
定义个普通类,继承抽象类,必须实现抽象类中的抽象方法
class Dog extends Animal{
void eat(){
System.out.println("狗吃骨头");
}
}
使用格式2
定义一个抽象类继承抽象类,不是必须要实现父类的抽象方法
abstract class Cat extends Animal{
}
4、注意事项
1、抽象类里面的方法可以是抽象的可以是非抽象的,可以全部是抽象的也可以全部是非抽象的
2、抽象类不能被实例化,是因为抽象类中可能包含抽象方法,实例化后调用抽象方法不知道干什么,所以没有意义
3、有抽象方法的类一定是抽象类,但是抽象方法可以存在于抽象类或者接口中
5、标准代码(写3次)
父类 |
abstract class Animal { public abstract void eat(); } |
子类1 |
class Dog extends Animal { public void eat() { System.out.println("eat 骨头"); } } |
子类2 |
class Cat extends Animal { public void eat() { System.out.println("eat 鱼"); } } |
测试类 | Animal animal = new Dog();
animal.eat(); Animal cat = new Cat(); cat.eat(); |
6、抽象类的基本特点(掌握)
1、抽象方法和抽象类用关键字abstract表示。
2、有抽象方法的类一定是抽象类(或者接口)。抽象类中不一定有抽象方法。
3、抽象类不能被实例化。
4、如果一个类继承抽象类,那么这个类要么本身也是抽象类。这个类 必须 重写父类的所有抽象方法。
7、抽象类的作用(掌握)
8、抽象类的成员特点(掌握)
1、成员变量
可以有成员变量,也可以有常量。
2、构造方法
有构造方法,但是不能通过构造方法创建对象
问:既然不能被实例化,那么有构造方法有什么用?
答:可以用于子类访问父类数据前,对父类数据进行初始化。
3、成员方法
1、可以有抽象方法,也可以有非抽象方法。
2、非抽象方法和抽象方法的作用
抽象方法是为了要求子类做某些事情。
非抽象方法是为了提高代码复用性,被子类继承。
9、抽象类的案例讲解(理解)
1、老师案例
2、学生案例
10、接口
我们可以把接口看成是一种特殊的抽象类。比抽象类更抽象。因为它里面的方法都是抽象的。但是注意,接口不是类,我们只是把他看成类
2、定义格式(掌握)
interface 接口名
{
//静态常量和抽象方法
}
3、使用格式
一个类实现一个接口
class 类名 implements 接口名1,接口名2...
{
//覆盖接口中的全部方法
}
一个抽象类实现一个接口,不必重写接口中的抽象方法
abstract class 类名 extends Object implements 接口1, 接口2,接口.....
{
//不需要全部都覆盖
}
一个接口继承一个接口
interface 接口名 extends 接口1,接口2..
{
}
11、接口的基本特点(掌握)
1、接口不能被实例化。
2、接口中的方法:
要么被子类重写。
要么子类也是抽象类。
12、接口的成员特点(掌握)
因为接口的成员变量有默认修饰符:public static final推荐:永远自己给出修饰符。
2、构造方法
没有构造方法//因为接口中的成员变量都被final修饰,定义的时候必须做初始化任何类如果没有继承父类,那么这个类就继承自Object类。//所有类都直接或者间接的继承自Object类。Object类是所有类的超类
3、成员方法:接口中的方法都是抽象的
因为接口中的成员方法有默认修饰符:public abstract
推荐:永远自己给出修饰符。
4、接口的注意事项
接口中不能有静态代码块,代码块,构造方法
13、接口的思想特点(了解)
接口是对外暴露的规则
接口是程序的功能扩展
接口的出现降低耦合性
接口可以用来多实现
14、抽象类和接口,类和接口的关系
1、抽象类和接口的关系(掌握)
抽象类:
成员变量:可以是变量,也可以是常量。
构造方法:有构造方法。
成员方法:可以是抽象方法,也可以是非抽象方法。
接口:
成员变量:只能是常量。
默认修饰符:public static final
成员方法:只能是抽象方法。
默认修饰符:public abstract
2、类与接口的关系(掌握)
类与类:
继承关系,只能单继承,可以多层继承。
类与接口:
实现关系,可以单实现,也可以多实现。
还可以在继承一个类的同时,实现多个接口。
接口与接口:
继承关系,可以单继承,也可以多继承。
3、设计理念的区别
抽象类被继承,这个类中定义的是整个继承体现的共性内容。
体现:is a
接口被实现,这个接口中定义的是整个体现的扩展内容。
体现:like a
15、什么时候定义抽象类,什么时候定义接口(掌握)
人刚生下来就具备哭的行为特征,但是每个人哭的行为不一样,所以人应该定义为抽象类,这些与生俱来的属性和行为应该定义在类里面
随着人的年纪的增加,会学习舞蹈,吉他,这些都是后天培养的拓展的功能,所以应该把学习跳舞和学习吉他定义为接口,这些后天学习的拓展功能应该定义在接口里
16、综合案例(理解)
乒乓球运动员和教练
篮球运动员和教练
为了出国交流,乒乓球运动员和教练需要说英语。
请你用所学知识,分析,这里应该有哪些类,抽象类,接口。
说英语接口 | interface SpeakEnglish
{ public abstract void speak(); } |
人的抽象类 | abstract class Person
{ private String name; private int age; public Person(){} public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } //睡觉的方法 public void sleep() { System.out.println("睡觉"); } //吃饭的方法 public abstract void eat(); } |
运动员的抽象类 | abstract class Player extends Person
{ public Player(){} //学习的方法 public abstract void study(); } |
教练的抽象类 | abstract class Coach extends Person
{ public Coach(){} //教的方法 public abstract void teach(); } |
乒乓球运动员 | class PingPangPlayer extends Player implements SpeakEnglish
{ public PingPangPlayer(){} public void speak() { System.out.println("乒乓球运动员学习英语"); } public void eat() { System.out.println("乒乓球运动员吃蛋炒饭"); } public void study() { System.out.println("乒乓球运动员学习如何接发球"); } } |
篮球运动员 | class BasketPlayer extends Player
{ public BasketPlayer(){} public void eat() { System.out.println("篮球运动员吃牛肉面"); } public void study() { System.out.println("篮球运动员学习如何运球,过人,投篮"); } } |
乒乓球教练 | class PingPangCoach extends Coach implements SpeakEnglish
{ public PingPangCoach(){} public void speak() { System.out.println("乒乓球教练学习英语"); } public void eat() { System.out.println("乒乓球教练吃白米饭"); } public void teach() { System.out.println("乒乓球教练教如何接发球"); } } |
篮球教练 | class BasketCoach extends Coach
{ public BasketCoach(){} public void eat() { System.out.println("篮球教练喝牛肉汤"); } public void teach() { System.out.println("篮球教练教如何运球,过人,投篮"); } } |
测试类 | class PersonTest
{ public static void main(String[] args) { //乒乓球运动员 PingPangPlayer ppp = new PingPangPlayer(); ppp.setName("邓亚萍"); ppp.setAge(50); System.out.println(ppp.getName()+"***"+ppp.getAge()); ppp.eat(); ppp.study(); ppp.speak(); //剩下的测试自己补齐 } } |
17、今天必须掌握的内容。以及常见的笔试题和面试题(学完这个就可以放心学习后面的知识了)
1、说说你对多态的理解
概念,特点(成员变量,成员方法,构造方法),注意事项,好处和弊端
2、说说你对抽象类和接口的理解
说说他们的由来,成员特点(成员变量,成员方法,构造方法),怎么用就可以了
3、今天的综合案例练熟(猫狗跳高案例,运动员教练案例)