多态的初识

简介: 多态的初识

1.代码分析

我们先来看一段关于值交换的代码

class MyValue {//定义一个MyValue类(类名注意采取大驼峰形式)
    public int val;
}
public class Test {
    public static void swap(MyValue x,MyValue y) {//值交换
        int temp = x.val;
        x.val = y.val;
        y.val = temp;
    }
    public static void main(String[] args) {
        MyValue val1 = new MyValue();
        val1.val = 10;
        MyValue val2 = new MyValue();
        val2.val = 20;
        swap(val1,val2);
        System.out.println(val1.val);
        System.out.println(val2.val);
    }


如果将public改成private,只需要利用get,set也可以进行值交换

注意:

get和set方法可以利用鼠标右键单击空白–》Generate–》getter and setter进行快捷调用

总结:

1.将Val1和 Val2的址传给x和y

2.x和y得到地址后,将里面的val值进行更改

3.Val1和 Val2所指对象的值也就进行了“交换”


2.多态

阐述:去完成某个行为,不同对象完成会产生不同的状态

2.1多态实现条件

继承
子类必须对父类中的方法进行重写
通过父类的引用调用重写的方法(向上转型)
class Person {//父类
    public String name;
    public int age;
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}
class Student extends Person {//子类--》Student
    public void study() {
        System.out.println(name + "正在学习");
    }
}
class Teacher extends Person {//子类--》Teacher
    public void teach() {
        System.out.println(name + "正在上课");
    }
}

2.1.1向上转型

3种表示方法

1.

注:向上转型只能访问父类自己的成员(属性/方法),不能访问子类的成员(属性/方法)

2.

3.


如果有小伙伴对第3种向上转型不理解,可以参考一下下面的截图

2.1.2重写

2.1.2.1重写需要满足的条件

方法名称相同
参数列表相同
返回值相同(如果不同,则必须构成父子类关系)

class Person {
    public String name;
    public int age;
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}
class Student extends Person {
    public void study() {
        System.out.println(name + "正在学习");
    }
    public void sleep() {
        System.out.println(name + "正在教室睡觉");
    }

此时的sleep方法就被重写了

2.1.2.2重写需要注意的点

private修饰的方法不能重写(访问权限受限制)
static修饰的方法不能重写(这种方法属于类方法)
子类的访问修饰限定权限要>=父类的权限
被final修饰的方法是不能重写的(此时这个方法被称作密封方法)

此时调用sleep方法就会执行子类的sleep方法,这是因为发生了动态绑定

实现动态绑定需满足的条件:
向上转型
重写
通过父类引用调用这个父类和子类重写的方法

动态绑定:运行时才知道调用的方法


那么有没有静态绑定呢?

答案是有的。

我们可以把重载理解为静态绑定的一种

静态绑定:编译时就知道要调用的方法


重写和重载的区别


2.2多态实现

class Person {
    public String name;
    public int age;
    public void sleep() {
        System.out.println(name + "正在睡觉");
    }
}
class Student extends Person {
    public void study() {
        System.out.println(name + "正在学习");
    }
    @Override//重写的注解
    public void sleep() {
        System.out.println(name + "正在教室睡觉");
    }
}
class Teacher extends Person {
    public void sleep() {
        System.out.println(name + "正在办公室睡觉");
    }
    public void teach() {
        System.out.println(name + "正在上课");
    }
}
public class Test1 {
    public static void method(Person person) {
        person.sleep();
    }
    public static void main(String[] args) {
        Person person1 = new Student();
        person1.name = "张三";
        method(person1);
        Person person2 = new Teacher();
        person2.name = "法外狂徒";
        method(person2);
    }
}

上面的代码就是多态的简单实现

当父类引用的对象不同时,其表现出的行为是不一样的


2.3向下转型

上图即为向下转型

向下转型较为不安全

如下:

此段代码虽然编译器没有报错,但运行时就会产生错误

如果一定要使用向下转型,可以搭配 instanceof 关键字

如下:

2.4 避免在构造方法中调用重写的方法

class B {
    public B() {
        func();
    }
    public void func() {
        System.out.println("B.func()");
    }
}
class D extends B {
    private int num = 1;
    public D() {
        super();
    }
    @Override
    public void func() {
        System.out.println("博哥真帅");
        //System.out.println("D.func() " + num);
    }
}
public class Test3 {
    public static void main(String[] args) {
        D d = new D();
    }
}

打印结果:

我们可以看到,程序先去执行的是子类的func,而不是父类中的func

注意:当在构造方法中调用重写方法时,会先去执行子类的重写方法

相关文章
|
编译器 C语言 C++
49 C++ - 多态
49 C++ - 多态
44 0
|
8月前
|
编译器 C++
多态的讲解
多态的讲解
59 2
多态你真的了解吗?
多态你真的了解吗?
78 0
|
8月前
深入理解多态
深入理解多态
|
8月前
|
C++
|
8月前
|
存储 编译器 C++
|
存储 编译器 C++
C++【多态】
C++多态,多态的概念、定义、实现和原理,以及虚函数和虚表的详细讲解,干货满满!
54 0
C++【多态】
|
编译器 C++
|
编译器 C++
多态(C++)上
多态(C++)
49 0

热门文章

最新文章