1、多态的概念## 标题
概念:就是一个事物在不同时候的不同状态,就比如人类,学生是人类的一种形态,工人也是人类的一种形态
多态:
父类的引用变量指向子类对象
格式:
父类类型 变量名=new 子类对象();
接口类型 变量名=new 子类对象();
使用前提条件:
必须有子父类关系或者接口和实现类的实现关系
在子类|实现类重写父类|接口的方法,否则多态没有意义
特点:
多态调用的是子类重写父类中的方法
代码实现:
定义父类
`package com.itheima.demo01duotai;
public class Fu {
public void show(){
System.out.println("Fu类的show方法!");
}
}`
定义抽象父类
package com.itheima.demo01duotai;
public abstract class Animal {
//抽象方法
public abstract void eat();
}
定义子类
package com.itheima.demo01duotai;
public class Zi extends Fu{
public void show(){
System.out.println("Zi类重写Fu类的show方法!");
}
}
定义测试类
package com.itheima.demo01duotai;
/*
多态:
父类的引用变量指向了子类的对象
格式:
父类类型 变量名 = new 子类对象();
接口类型 变量名 = new 实现类对象();
使用前提:
1.必须有子父类关系或者接口和实现类的实现关系
2.在子类|实现类中重写父类|接口中的方法,否则多态没有意义
特点:
1.多态调用的是子类重写后的方法
2.如果有多个子类,创建的是哪个子类对象,调用哪个子类重写后的方法
*/
public class Demo01 {
public static void main(String[] args) {
//普通类的多态 父类:Fu 子类:Zi
Fu fu = new Zi();
fu.show();//Zi类重写Fu类的show方法!
//抽象类多态 父类:Animal 子类:Cat,Dog
Animal a = new Cat();
a.eat();//猫吃鱼!
a = new Dog();
a.eat();//狗吃肉!
}
}
2、多态的好处和弊端## 标题
好处:扩展性强,父类的变量可以赋值不同的子类对象,调用子类重写后的方法
弊端:不能直接调用子类特有的功能
多态的实际应用:一般把父类类型作为方法的返回值和参数来使用
3、多态的转型## 标题
多态的向上转型:多态的本身就是向上转型,把子类对象赋值给父类的变量
格式:父类类型 变量名=new 子类对象();
好处:扩展性强,可以赋值给不同的子类对象,调用子类重写后的方法
多态的向下转型:就是把父类类型的变量强转成子类类型(强转)
格式:子类类型 变量名 =(子类类型)父类变量名;
好处:父类变量强转成子类类型,就可以使用子类的功能
注意:多态是向下转型的前提,直接创建父类对象,不能向下转型
代码实现:
父类
package com.itheima.demo03duotai;
public class Fu {
public void work(){
System.out.println("父类在工作!");
}
}
子类
package com.itheima.demo03duotai;
public class Zi extends Fu{
@Override
public void work() {
System.out.println("儿子在工作!");
}
//定义一个Zi类特有的玩游戏的方法
public void playGame(){
System.out.println("儿子在玩游戏!");
}
}
测试类
package com.itheima.demo03duotai;
import com.itheima.demo02duotai.Animal;
import com.itheima.demo02duotai.Cat;
import com.itheima.demo02duotai.Dog;
/*
多态的转型:
1.向上转型:多态本身就是向上转型,把子类对象赋值给父类的变量
格式:
父类类型 变量名 = new 子类对象():
好处:
扩展性强,可以赋值不同的子类对象,而调用不同子类重写后的方法
--------------------------------------------------------------
int a = 10;
double d = a;
2.向下转型:把父类类型的变量强制转换为子类类型(强转)
格式:
子类类型 变量名 = (子类类型)父类变量名;
好处:
强制之后,多态变量变成了子类类型,就可以使用子类特有的功能
注意:
a.向下转型前提,必须是多态
b.直接创建父类对象,不能向下转型
-----------------------------------------------------------------
double d = 5.5;
int a = (int)d;
*/
public class Demo01 {
public static void main(String[] args) {
/*
1.向上转型:多态本身就是向上转型,把子类对象赋值给父类的变量
父亲病了,不能工作,儿子化妆成父亲,替父亲工作
*/
Fu f = new Zi();
f.work();//儿子在工作!
//儿子替父亲工作完了,想玩游戏;表现是父类的形态,父亲是没有玩游戏的方法,不能玩
//f.palyGame();//Cannot resolve method 'palyGame()'
/*
2.向下转型:把父类类型的变量强制转换为子类类型(强转)
儿子完成工作,卸妆变回儿子
*/
Zi zi = (Zi)f;
zi.playGame();
//直接创建父类对象,不能向下转型
Fu fu = new Fu();
//Zi z = (Zi)fu;//类型转换异常:ClassCastException: com.itheima.demo03duotai.Fu cannot be cast to com.itheima.demo03duotai.Zi
System.out.println("--------------------------");
Animal a = new Cat();//向上转型
a.eat();
a.sleep();
Cat c = (Cat)a;//向下转型
c.catchMouse();
//Dog d = (Dog)a;//把猫转换为狗 ClassCastException: com.itheima.demo02duotai.Cat cannot be cast to com.itheima.demo02duotai.Dog
}
}
3、匿名内部类
匿名内部类是在一个类中创建的没有名字的一个类,
主要作用:简化代码,将创建子类对象,子类继承父类,重写父类方法合为一步。
代码实现:
父类:
package com.demo07innerClass;
public abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
子类
package com.demo07innerClass;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
@Override
public void sleep() {
System.out.println("猫随心所欲的睡!");
}
//定义猫特有的抓老鼠的方法
public void catchMouse(){
System.out.println("猫和老鼠一起玩耍!");
}
}
测试类
package com.demo07innerClass;
/*
匿名内部类(重点):
匿名:创建内部类,不像Cat.Dog有类名,没有具体的类名
内部类:是一个局部内部类(写在方法中)
作用:简化代码
把子类继承父类,重写父类的方法,创建子类对象合成一步完成
把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成
格式:
new 父类|接口(){
重写父类|接口中的方法;
};
------------------------------------------------
new Animal(){
@Override
public void eat() {
System.out.println("动物在吃饭");
}
@Override
public void sleep() {
System.out.println("动物在睡觉!");
}
};
以上一堆代码就是一个创建子类对象的过程,相当于new Cat();
*/
public class Demo01InnerClass {
public static void main(String[] args) {
//匿名对象:只能使用一次
new Cat().eat();
new Cat().sleep();
System.out.println("------------------------");
//匿名内部类
new Animal(){
@Override
public void eat() {
System.out.println("动物在吃饭");
}
@Override
public void sleep() {
System.out.println("动物在睡觉!");
}
}.eat();
new Animal(){
@Override
public void eat() {
System.out.println("动物在吃饭");
}
@Override
public void sleep() {
System.out.println("动物在睡觉!");
}
}.sleep();
/*new Animal(){
@Override
public void eat() {
System.out.println("动物在吃饭");
}
@Override
public void sleep() {
System.out.println("动物在睡觉!");
}
public void catchMouse(){
System.out.println("猫和老鼠一起玩耍!");
}
}.catchMouse();*/
System.out.println("----------------------------------");
//多态 父类 = 子类对象
Animal a = new Cat();
a.eat();
a.sleep();
System.out.println("----------------------------------");
//多态 父类 = 子类对象
Animal a2 = new Animal(){
@Override
public void eat() {
System.out.println("动物在吃饭!");
}
@Override
public void sleep() {
System.out.println("动物在睡觉!");
}
};
a2.eat();
a2.sleep();
}
}