写在前面:
视频是什么东西,有看文档精彩吗?
视频是什么东西,有看文档速度快吗?
视频是什么东西,有看文档效率高吗?
待到吃饱喝足之后。。。。
“师弟,我先睡一会儿,你自便”说罢,诸小亮便走近了卧室
但张小飞飞却不想休息,正苦恼做什么,突然发现桌子上有一枚硬币,像发现宝物似的紧紧握在手里。
“正面看电影,反面打王者,竖着就学习,斜着就加班,摔碎了就熬夜学习,如果摔成俩-----
那就什么都不干了,坐在家里天天摔……!”
诸小亮:。。。。。
1. 多态
下午。
诸小亮:多态——就是事物的多种形态
张小飞:额…,能举个例子吗?
“比如:泰迪是狗,属于犬科,也是动物,更是生物”
“这样啊,那,水在常温下是液体,0度下是固体,100度是气体,这也是多态?”
“是这个道理,举一反三的能力挺不错的”
“呵呵,还好,不过这跟 Java 有什么关系?”
“Java中多态,说的是:对象的多态性”
- 就是:父类或者父接口类型的引用指向子类对象
示例:
interface Animal{
void sound();
void eat();
}
class Dog implements Animal {
@Override
public void sound(){
System.out.println("汪汪汪。。。。。");
}
@Override
public void eat() {
System.out.println("骨头。。。。。");
}
}
public class Demo{
public static void main(String[] args){
//多态:父类或父接口的引用指向子类对象
Animal dog = new Dog();//Dog对象,既是Dog类型,又是Animal类型,这就是多态
}
}
张小飞:“原来在 Java 中,这就是多态,不过这有什么用?”
2. 多态的好处
诸小亮:这好处就太多了
- 使用父类或者父接口类型的变量,可以接收其所有子类的对象,提高代码的复用率
张小飞:还能提高代码复用率?
“是的,举个例子:狗在吃东西前会做一些事情,比如:叫几声”
public static void main(String[] args
//泰迪
Dog taidi = new Dog();
taidi.sound();
taidi.sound();
taidi.eat();
//藏獒
Dog zangao = new Dog();
zangao.sound();
zangao.sound();
zangao.eat();
}
“上面的代码很类似,所以可以用方法封装一下:”
//用一个方法封装狗吃东西时都做什么
public static void dogEat(Dog dog){
dog.sound();
dog.sound();
dog.eat();
}
//这段代码要比上面的简介一些
public static void main(String[] args){
Dog taidi = new Dog();
dogEat(taidi);
Dog zangao = new Dog();
dogEat(zangao);
}
张小飞:“这跟多态没关系吧”
“不要着急,继续看:猫也一样,在吃东西前会做一些事情,像:叫几声”
interface Animal{
void sound();
void eat();
}
class Dog implements Animal {
@Override
public void sound(){
System.out.println("汪汪汪。。。。。");
}
@Override
public void eat() {
System.out.println("骨头。。。。。");
}
}
class Cat implements Animal{
@Override
public void sound() {
System.out.println("喵喵喵。。。。。");
}
@Override
public void eat() {
System.out.println("鱼。。。。。");
}
}
public class Demo2{
public static void main(String[] args){
Dog taidi = new Dog();
dogEat(taidi);
Dog zangao = new Dog();
dogEat(zangao);
Cat jiafeimao= new Cat();
//Cat 不能使用 dogEat 方法,只能创建一个新的 catEat 方法
catEat(jiafeimao);
Cat tangmu = new Cat();
catEat(tangmu);
}
//用一个方法封装狗吃东西时都做什么
public static void dogEat(Dog dog){
dog.sound();
dog.sound();
dog.eat();
}
//用一个方法封装猫吃东西时都做什么
public static void catEat(Cat cat){
cat.sound();
cat.sound();
cat.eat();
}
}
诸小亮:“有没有发现,dogEat 和 catEat 方法差不多,所以这俩方法还可以合并”
张小飞:“不能把,他们的参数类型不同啊”
“这时候就可以用多态了,因为Dog 和 Cat 都是Animal,所以:”
//抽出一个公共的方法,参数是 Animal 类型,只要是 Animal 的子类都可以传进来
public static void animalEat(Animal animal){
animal.sound();
animal.sound();
animal.eat();
}
public static void main(String[] args){
Animal dog1 = new Dog();
animalEat(dog1);
Animal dog2 = new Dog();
animalEat(dog2);
Animal cat1 = new Cat();
animalEat(cat1);
Animal cat2 = new Cat();
animalEat(cat2);
}
张小飞:“原来是这样,明白了”
3. 弊端
诸小亮:“但其实它也有弊端”
张小飞:“什么弊端?”
“只能使用父类或父接口中的方法,不能使用子类的特有方法,比如:”
//狗都有看家的功能
public void seeHome() {
System.out.println("看家,汪汪汪。。。。。");
}
“但是 Animal 没有‘seeHome’的功能,如果使用多态,不能调用 seeHome 方法”
解释:虽然创建的对象是 Dog ,但是作为一个 Animal ,无法使用 Dog 的特有方法
张小飞:那如果就是想用 Dog 的特有方法呢?
诸小亮:这时可以向下转型
4. 向上向下转型
诸小亮:这句代码:Animal dog = new Dog(); 专业说法叫:向上转型
张小飞:那,什么是向下转型呢?
“看下面代码:”
张小飞:“这不就是——强制类型转换么?”
“是的,但是需要注意:”
public static void main(String[] args){
//animal 是一个猫
Animal animal = new Cat();
//不能强制转换位Dog类型,这样虽然编译不报错,但是运行时会出问题
Dog d = (Dog) animal;
d.seeHome();
}
结果:
张小飞:“那,如何判断 animal 具体是哪一种子类型呢?”
“使用 instanceof 就可以了,比如:”
public static void main(String[] args){
Animal animal = new Cat();
//instanceof:判断变量是不是对应类型
if(animal instanceof Dog){
Dog d = (Dog) dog;
d.seeHome();
}else{
System.out.println("不是狗东西。。。。");
}
}
5. 多态时的成员和方法
诸小亮:不过,使用多态,当子父类中有相同属性和方法时,需要注意两点
张小飞:具体是哪两点?
“第一:子父类中有同名属性时,使用父类中的属性,比如:”
class Animal{
int num = 2;
}
class Dog extends Animal {
int num = 3;
}
public class Demo2{
public static void main(String[] args){
Animal dog = new Dog();
System.out.println(dog.num);//输出2
}
}
“第二:子父类中有相同方法时,运行的是子类中的方法,比如:”
class Animal{
int num = 2;
void run(){
System.out.println("疯狂动物城。。。。。");
}
}
class Dog extends Animal {
int num = 3;
void run(){
System.out.println("狗狗跑起来。。。。。");
}
}
public class Demo2{
public static void main(String[] args){
Animal dog = new Dog();
dog.run();//实际调用的是 Dog 类中的 run 方法
}
}
结果:
张小飞:明白了
诸小亮:好了,多态就说这么多,你好好的回顾一下