Java se的语言特征之多态

发布时间:2023年12月18日

满足多态的条件

定义:去完成某个状态的时候,当不同的对象去完成的时候会产生不同状态(通俗理解为看人下菜)

满足多态的条件:
1>必须在继承关系上,才可以向上转型
2>子类和父类有同名的覆盖(重写)方法
3>通过父类对象的引用,去调用这个重写的方法
完成以上的三个部分,就会发生动态绑定,动态绑定为多态的基础

通过父类的引用,只能调用父类自己独有的属性,方法,构造方法

动态绑定第一步

向上转型:子类定义的变量,方法给父类

Dog dog = new Dog("小黄",8);
Animal animal = dog;
Animal animal = new Dog("小黄", 8);

这个被称为直接赋值型
是通过animal这个引用指向了dog这个引用所指向的对象

传参时候进行向上转型(方法的参数)

public static void func1(Animal animal){

}
public static void main(String [ ] args){
         Dog dog = new Dog("小黄",8);
         func1(dog);
}

返回值进行向上转型

public static Animal func2( ){
       Dog dog = new Dog("小黄", 8);
       return dog;
}

动态绑定第二步

public static Animal func2( ){
     System.out.println(this.name + "吃饭");
}
@Override(可以在此写注释,起到防止错误作用)
public void eat( ){
     System.out.println(this.name + "吃狗粮");
}

注意:
1>在这里面,返回值,方法名以及参数链表要相同
2>被重写的访问修饰限定符,子类一定要大于父类
3>被private修饰的方法不可重写
4>被static修饰的方法不可以重写
5>被final修饰的方法不可重写
6>构造方法不可以重写

动态绑定第三步

Animal animal  = new Dog("小黄",8);
animal eat( );

在产生了重写以后,animal忽然就变成了调用子类的eat.这个过程就叫做动态绑定

父类与子类也可以构成重写,被称为协变类型

public Dog eat( ){
     System.out.println(this.name + "吃饭");
     return null;
}
public Animal eat( ){
     System.out.println(this.name + "吃狗粮");
}

所有的父类,默认都是Object类

public static void eatFun(Animal animal){
    animal.aet( );
}
public static void main(String [ ] args){
   Dog dog  = new Dog("小黄", 8);
   eatFun(dog);
   Cat cat = new Cat("三月",6);
   eatFun(cat);
}

当父类的引用,引用的子类对象不一样的时候,调用这个重写的方法,表现出的行为是不一样的,我们把这种思想叫做多态

参数列表,返回类型,访问修饰限定符区别

在这里插入图片描述

有动态绑定,那是不是有静态绑定

add(int a, int b)
add(int a, int b, int c)
main( ){
    add(1, 2);
    add(1, 2 ,3);
}

这上面这种就是静态绑定

向下转型

顾名思义,就是父类给子类

Animal animal = new Dog("小黄", 8 );
//狗可以为一个动物
Animal animal = new Cat ("三月", 6);
//猫也可以为一个动物

Animal animal = new Dog("小黄", 8 );
Dog dog = animal;
//但是在这个里面,动物不一定是狗,
//所以向下转型是不安全的

Animal animal = new Dog ("小黄", 8 );
Dog dog = (Dog) animal;
//因为本身不安全的,所以这里要进行强转
dog.bark( );

Cat cat = (Cat)animal;
cat.miaomaio( );
//这里的话就会错,因为animal在上面是引用对象为Dog,
//所以dog可以成功转型,Cat就不可以

在父类的构造方法里面,可以调用子类和父类重写的方法,此时会调用子类的方法,此时也会发生动态绑定,但是注意,不可以这么写

抽象类

abstract class Shape{
     public abstract void draw( );
}

1>abstract修饰的类,方法为抽象类(方法)
2>抽象类不可以实例化一个对象
3>抽象类中可以和普通类一样,定义方法和变量
4>当一个普通类继承了抽象类,那么要重写这个抽象类中的抽象方法
5>抽象类的出现就是为了被继承
6>abstract 和 final 是天敌,不可以共存
7>被private static 修饰的这个抽象方法也不可以

接口

语法:
1>interface方法来修饰的(就是创建方法时候,把class换成interface)
2>接口中不可以被实现的方法,只有抽象方法(static , deafult修饰的不受限制)
3>接口中的抽象方法,默认都是public abstarct 修饰的
4>接口中的成员变量,默认都是public static final修饰的
5>接口不能进行实例化
6>类和接口之间的关系,可以使用implements来进行关联
7>接口也有对应的字节码文件

注意:
1>接口中的方法不可以在接口中实现,只能由实现接口的类来实现
2>接口中不能包含构造方法,以及静态代码块

实现多个接口(先继承再接口,接口用",")

interface A{
    void test A( );
}
interface B extends A{
    void test B( );
}

这个里面的话,B也具备了A的功能,但是后面用接口B的时候,B和A都要重新实现

2个关系
1>类与接口之间的关系,用implements
2>接口与接口之间的关系,用extends

文章来源:https://blog.csdn.net/weixin_52689187/article/details/134939952
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。