java多态理解通俗,说说 Java 多态那些事儿~

冷不防 2023-01-16 03:24 230阅读 0赞

都说面向对象有三大特性:封装、继承、多态。前两个在 Python 中很常见,也一直再用,就不特别整理了。但是在多态这个地方就跟 Java 有点不同。我们仔细研究一下看看。

多态 Polymorphism 分为两种,编译时多态,就是函数重载啦(overload)注意与下面的 override 区别一下。还有一个是运行时多态,我们今天主要研究研究这个。

要想理解好多态,我们得先知道 emmm 很多事情,,,,让我一件一件来说。

  1. 强制类型转换

首先就是 Java 中的类型转换,其实这个没啥可说的,只是需要注意一件事情,类型转换数据本身没有变化。比如下面这段代码,变量 a 一直都是一个 char 类型的变量,只是将它暂时作为 int 型的变量使用一下。

class Hello{

public static void main(String [] args){

char a = ‘a’;

int num = a;

System.out.print(num);

}

}

  1. 覆写

在继承关系中,子类如果定义了一个与父类方法完全相同(函数名、参数列表、返回值类型)的方法,被称为覆写(Override)。

注意与重载(Overload)进行区分,重载是指一个类中的两个方法函数名和返回值一样,但是参数列表不同。

另外:方法名相同,方法参数相同,但方法返回值不同,也是不同的方法。在Java程序中,出现这种情况,编译器会报错。

  1. 程序绑定

绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。分为静态绑定和动态绑定。

直接举个动态绑定的例子吧,比如说有人结婚邀请你家去参加婚礼,但是具体谁去还不一定,有可能是你妈妈,有可能是你,有可能是你妹妹,这要看当时你们家谁有空(说不定后来你们家来了个亲戚,婚礼的时候你们都没空,就让他去了)。要是静态绑定呢,指定是谁,就必须是谁,而且编译的时候这个人必须已经存在。

比如我对于静态绑定(像 C 语言),指定使用哪个对象就是哪个对象,指定哪个属性,这个属性就必须存在。

对于动态绑定(比如 Python 支持的动态绑定),调用一个对象的方法,如果这个方法里使用到了一个属性,但是我的这个类还没有这个属性,它是在运行过程中产生的。也不用管这个属性属于哪个对象,这个属性是啥时候才有的,只要在我执行这个方法的时候这个对象里面有我想要的属性就 ok 。

Java 是一个比较折衷的语言,java 当中的方法只有 final,static,private 和构造方法是静态绑定,剩下的都是动态绑定。

  1. 上转型对象

然后就是上转型对象,简单点来说,上转型对象就是对象级别的强制类型转换。这是一个 引用变量的声明类型与其实际类型不符 的例子。

将子类对象赋值给一个父类的引用类型变量,(将子类理解为一个父类使用,没有转化!!)这个父类引用所指向的对象就叫上转型对象。

23317e8cb27e

上转型对象的特点:

父类引用不能访问子类新增的成员(属性和方法);

父类引用访问父类中被隐藏属性时访问的是子类继承(父类)的属性。

父类引用调用被子类覆写的父类方法时调用的是子类覆写后的方法

(有没有想起来 C++ 中的虚函数)

上转型对象就是动态绑定的一个体现,比如在使用父类引用调用被子类重写的方法的时候,我不去管这个对象是哪个类的,只要里面有我要的方法就行,自然这样调用的就是被子类重写的方法。

我们先来看一个例子:

public class Area{

public static void main(String[] args){

Animal dog1 = new Dog();

dog1.run();

System.out.println(dog1.age);

}

}

class Animal{

public int age = 0;

public void run(){

System.out.println(“动物跑。。。”);

}

}

class Dog extends Animal{

public int age = 100;

@Override

public void run(){

System.out.println(“狗跑。。。”);

}

}

## 狗跑。。。

## 0

注意这个结果,方法可以被覆写,所以使用的是覆写之后的方法,但是属性没有覆写这一说,所以使用的就还是父类继承下来的属性。

还有在子类里面可以使用装饰器 @Override 标识一个覆写函数,这样解释器就可以帮我们检查是否真的是覆写。

不同的子类覆写的方式也不同,这样调用相同的父类方法,对于不同的子类,所得到的结果就不同,这就是多态的效果。

  1. 多态

正如上文所说,多态就是 同样的行为(同一段代码)作用于不同对象时产生不同的效果。

多态想要解决的问题主要是:设计和实现的分离,这样修改设计,修改实现都非常容易。另外这样写的话代码量也会比较少,也比较容易阅读。

比如看下面这个代码:

public class TestPolymorphism{

public static void main(String [] args){

Dog dog = new Dog();

Cat cat = new Cat();

Bird bird = new Bird();

dog.saySomething();

cat.saySomething();

bird.saySomething();

}

}

class Dog{

public void saySomething(){

System.out.println(“汪汪汪……”);

}

}

class Cat{

public void saySomething(){

System.out.println(“喵喵喵……”);

}

}

class Bird{

public void saySomething(){

System.out.println(“啾啾啾……”);

}

}

这个例子太经典了….

下看一下使用多态的实现

class TestPolymorphism{

public static void animalSaySomthing(Animal an){

an.saySomething();

}

public static void main(String [] args){

Dog dog = new Dog();

Cat cat = new Cat();

Bird bird = new Bird();

animalSaySomthing(dog);

animalSaySomthing(cat);

animalSaySomthing(bird);

}

}

class Animal{

public void saySomething(){}

}

class Dog extends Animal{

public void saySomething(){

System.out.println(“汪汪汪……”);

}

}

class Cat extends Animal{

public void saySomething(){

System.out.println(“喵喵喵……”);

}

}

class Bird extends Animal{

public void saySomething(){

System.out.println(“啾啾啾……”);

}

}

当我们不光想要动物叫还想让他们做其他事情的时候,多态的好处就显现出来了,比如说我还想增加跑,吃,上树的方法,按照第一个的话那就需要为每一个都增加一个方法,然后每一个调用一遍,但是使用多态的话我们只需要在Animal 类中增加相应的接口,然后在子类中实现它。

额,,看到这里你一定会说这不是更麻烦了嘛,,,emmm,对于这个例子来说确实是这样,在实际生产环境中,也就是对于大型程序,多态主要是用在接口中,那个时候才能真正体现 Polymorphism 的作用。

发表评论

表情:
评论列表 (有 0 条评论,230人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java_-java

    Java 多态 多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口,使用不同的实例而执行不同操作。 多态的优点 三个必要条件 虚函数 重写 多

    相关 理解java

    面向对象编程有三大特性:封装、继承、多态。        封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏

    相关 Java理解

    Java中多态性的实现 什么是多态 1. 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的

    相关 java理解

    有三个类:Animal父类,Dog子类(继承父类Animal)、Cat子类(继承父类Animal) 注:Animal可以是抽象类、接口。 1、多态、动态调用(后期编译):