Java基础——多态

多态

1、方法的多态


package day02;

public class Demo2 {
    public static void main(String[] args) {
        // 方法重载体现多态
        B b = new B();
        b.sum(10, 20);
        b.sum(10, 20, 30);

        // 方法重写体现多态
        A a = new A();
        a.say();
        b.say();

    }
}
class A{
    public void say(){
        System.out.println("A say()");
    }
}
class B extends A{
    public void sum(int n1, int n2){
        System.out.println(n1 + n2);
    }
    public void sum(int n1, int n2, int n3) {
        System.out.println(n1 + n2 + n3);
    }

    @Override
    public void say() {
        System.out.println("B say()");
    }
}

2、对象的多态(核心,困难,重点)

  1. 一个对象的编译类型和运行类型可以不一致
  2. 编译类型在定义对象时,就确定了,不能改变
  3. 运行类型是可以变化的
  4. 编译类型看定义时=号的左边,运行类型看=号的右边

多态的细节(共 6 点):

  1. 多态的前提是:两个对象(类)存在继承关系
  2. 多态的向上转型:
    本质:父类的引用指向了子类的对象
    语法:父类类型引用名 = new 子类类型();
    特点:编译类型看左边,运行类型看右边。
  3. 可以调用父类中的所有成员(需遵守访问权限),不能调用子类中特有成员;最终运行效果看子类的具体实现!

package day02;

public class Demo3 {
    public static void main(String[] args) {
        // 向上转型:父类引用指向子类对象
        // 父类类型 对象名 = new 子类类型()
        Animal animal = new Cat();
        Object obj = new Cat();

        // 1.可以调用父类中的所有成员(但必须遵守访问权限),不能调用子类的特有成员。
        // 因为如果调用子类的特有成员,在编译期间就会报错。即:一个对象能调用哪些成员,是由编译类型决定的
        // 所以:animal.catchMouse();错误
        // 2.最终运行效果看子类的具体实现,即运行期间调用方法时,按照从子类开始查找方法,然后调用。
        // 所以:animal.eat();会执行 Cat 类中重写的 eat 方法
        animal.eat(); // 猫吃鱼
        animal.run();
        animal.sleep();
        animal.show();
    }
}
class Animal{
    private String name;

    public void run(){
        System.out.println("动物跑");
    }
    public void eat(){
        System.out.println("动物吃");
    }
    public void sleep(){
        System.out.println("动物睡");
    }
    public void show(){
        System.out.println("动物:Hello~");
    }

}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

  1. 多态的向下转型:
    (1)语法:子类类型引用名 = (子类类型)父类引用;
    (2)只能强转父类的引用,不能强转父类的对象
    (3)要求父类的引用必须指向的是当前目标类型的对象
    (4)当向下转型后,可以调用子类类型中所有的成员

package day02;

public class Demo3 {
    public static void main(String[] args) {
        // 向上转型:父类引用指向子类对象
        // 父类类型 对象名 = new 子类类型()
        Animal animal = new Cat();
        Object obj = new Cat();


        // 多态的向下转型
        // 要求:子类类型 子类引用 = (子类类型)父类引用;
        //      父类的引用必须指向的是当前目标类型的对象
        Cat cat = (Cat) animal;
        cat.eat();          // 猫吃鱼
        cat.catchMouse();   // 猫抓老鼠

    }
}
class Animal{
    private String name;

    public void run(){
        System.out.println("动物跑");
    }
    public void eat(){
        System.out.println("动物吃");
    }
    public void sleep(){
        System.out.println("动物睡");
    }
    public void show(){
        System.out.println("动物:Hello~");
    }

}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

  1. 属性没有重写之说,属性的值看编译类型:

package day02;

public class Demo4 {
    public static void main(String[] args) {
        // 属性没有重写之说,属性的值看编译类型
        Sub sub = new Sub();
        System.out.println(sub.n);// 20

        // 属性没有重写之说,属性的值看编译类型
        // 编译类型为 Base,所以属性值为 Base 中的值
        Base base = new Sub();
        System.out.println(base.n);// 10

    }
}
class Base{
    int n = 10;
}
class Sub extends Base{
    int n = 20;
}

  1. instanceOf比较操作符,用于判断对象的 运行类型 是否为XX类型或XX类型的子类型

package day02;

public class Demo4 {
    public static void main(String[] args) {
        BB bb = new BB();
        System.out.println(bb instanceof BB);// true
        System.out.println(bb instanceof AA);// true

        // 编译类型 AA, 运行类型 BB
        AA aa = new BB();
        System.out.println(aa instanceof AA);//true
        System.out.println(aa instanceof BB);//true

    }
}
class AA{
}
class BB extends AA{
}

练习


package day02;

public class Demo4 {
    public static void main(String[] args) {
        Sub sub = new Sub();
        System.out.println(sub.count); // 20
        sub.display();                 // 20

        Base b = sub;
        System.out.println(b == sub);  // true
        System.out.println(b.count);   // 10
        b.display();                   // 20
    }
}
class Base{
    int count = 10;
    public void display(){
        System.out.println(this.count);
    }
}
class Sub extends  Base{
    int count = 20;

    @Override
    public void display() {
        System.out.println(this.count);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值