加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java 多态

发布时间:2020-12-15 07:24:26 所属栏目:Java 来源:网络整理
导读:多态:一个对象有多种形态 是方法的多态,和属性无关 有继承关系、 重写方法 、父类引用 指向 子类对象 静态方法不支持多态 举例, 有父类Dog,属性name="dog",普通方法say,静态方法move; 子类SDog,属性name="sdog",重写了普通方法say,重写了静态方法m

多态:一个对象有多种形态

  • 是方法的多态,和属性无关
  • 有继承关系、重写方法、父类引用 指向 子类对象
  • 静态方法不支持多态

举例,

有父类Dog,属性name="dog",普通方法say,静态方法move;

子类SDog,属性name="sdog",重写了普通方法say,重写了静态方法move,另外有自己的普通方法sd;

子类BDog,属性name="bdog",重写了普通方法say,重写了静态方法move,另外有自己的方法bd;

孙类SDog_son继承了SDog,属性name="sdog_son",重写了普通方法say,重写了静态方法move;

测试代码:

package my_test;

public class Main {
    public static void main(String[] args) {
        Dog d1;//d1是一个引用
        d1=new Dog();//d1 指向父类Dog创建的对象
        d1.say();
        d1.move();
        System.out.println(d1.name);
        System.out.println("------------------------------------------");
        d1=new SDog();//d1 指向子类SDog创建的对象,上面失去引用的对象会被回收
        d1.say();
        d1.move();
        System.out.println(d1.name);
        System.out.println("------------------------------------------");
        //d1.sd();//报错,因为Dog中没有sd()方法.The method sd() is undefined for the type Dog
        d1=new BDog();
        d1.say();
        d1.move();
        System.out.println(d1.name);
        //d1.bd();//报错,同上
        System.out.println("------------------------------------------");
        d1=new SDog_son();//d1 指向孙类SDog_son创建的对象,上面失去引用的SDog对象会被回收
        d1.say();
        d1.move();
        System.out.println(d1.name);
        System.out.println("------------------------------------------");
    }

}
class Dog {
    String name="dog";
    public void say() {
        System.out.println("dog_say");
    }
    public static void move() {
        System.out.println("dog_move");
    }
    
}

class SDog extends Dog{
    String name="sdog";
    public void say() {
        System.out.println("sdog_say");
    }
    public static void move() {
        System.out.println("sdog_move");
    }
    public void sd() {
        System.out.println("sdog自己独特的方法sd");
    }
    
}

class BDog extends Dog{
    String name="bdog";
    public void say() {
        System.out.println("bdog_say");
    }
    public static void move() {
        System.out.println("bdog_move");
    }
    public void bd() {
        System.out.println("bdog自己独特的方法bd");
    }
}

class SDog_son extends SDog{
    String name="sdog_son";
    public void say() {
        System.out.println("sdog_son_say");
    }
    public static void move() {
        System.out.println("sdog_son_move");
    }
}


class Factory{//没有报错,将用于工厂方法模式
    public Dog createdog(int id) {
        if(id==1)
            return new Dog();
        else if(id==2)
            return new SDog();
        else 
            return new BDog();
    }
}

输出:

dog_say
dog_move
dog
------------------------------------------
sdog_say
dog_move
dog
------------------------------------------
bdog_say
dog_move
dog
------------------------------------------
sdog_son_say
dog_move
dog
------------------------------------------

Dog的引用 指向 不同的子孙类对象的各种情况下:

1.调用普通方法say,输出是各自子孙类的重写方法,并且调用子类自己的方法sd()和bd()会报错。验证:继承的重写方法 支持多态

2.调用静态方法move,输出的都是父类的静态方法内容。验证:静态方法不支持多态

3.System.out.println(d1.name);输出的都是dog。验证:多态和属性无关

?

另附一些理解:

1.d1这个变量是引用,放在内存栈里。new出来的东西放在内存堆里,引用即栈指向堆。

2.编译时多态(也称静态多态,也就是调用静态方法的多态),因为编译时就加载了静态的代码块,存在静态常量池里。

3.运行时多态(也就是通常说的多态,因为大家都觉得静态方法不支持多态,实际上只是没体现出来,而我们需要解决的问题是通过运行时多态解决的,所以我们说的多态都是运行时多态),编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。(多态方法又被称为延迟方法的原因)。实现技术叫:动态绑定。编译时只加载静态代码,运行时才加载普通代码,当类被载入到虚拟机内部的时候,在内存中产生类的常量池叫运行时常量池。

4.静态方法可以通过类名调用,不妨理解为:d1是Dog的变量,调用静态方式是通过类调用,即d1.move()就是Dog.move()

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读