-
2022-03-18 23:34:59
Java多态和Python多态
ava中的多态跟Python中的多态是有区别的。
java中的多态定义:
多态存在的三个必要条件
一、要有继承;
二、要有重写;
三、父类引用指向子类对象java 多态演示
public class Test { public static void main(String[] args) { show(new Cat()); // 以 Cat 对象调用 show 方法 show(new Dog()); // 以 Dog 对象调用 show 方法 Animal a = new Cat(); // 向上转型 a.eat(); // 调用的是 Cat 的 eat Cat c = (Cat)a; // 向下转型 c.work(); // 调用的是 Cat 的 work } public static void show(Animal a) { a.eat(); // 类型判断 if (a instanceof Cat) { // 猫做的事情 Cat c = (Cat)a; c.work(); } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a; c.work(); } } } abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void work() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void work() { System.out.println("看家"); } } 执行以上程序,输出结果为: 吃鱼 抓老鼠 吃骨头 看家 吃鱼 抓老鼠
Python 的继承 和Java 的继承
python和java在继承方面最大的区别就是python子类可以继承多个父类,但是java子类只能继承一个父类,如果一个子类需要多继承的话一般设计成interface接口的方式来实现。
比如创造一个child类,类型father和mother。在Python中,father类和mother类可以都设计成child的父类,但在java中可以设计成father父类和mother接口,继承需要extends关键字实现,接口需要implements关键字实现python 实现
class child (father, mother):Java 实现
class child extends father implements mother
Python 多态
让具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容(功能)的函数。
Python中多态的特点
1、只关心对象的实例方法是否同名,不关心对象所属的类型;
2、对象所属的类之间,继承关系可有可无;
3、多态的好处可以增加代码的外部调用灵活度,让代码更加通用,兼容性比较强;
4、多态是调用方法的技巧,不会影响到类的内部设计。多态的应用场景
1. 对象所属的类之间没有继承关系
调用同一个函数fly(), 传入不同的参数(对象),可以达成不同的功能class Duck(object): # 鸭子类 def fly(self): print("鸭子沿着地面飞起来了") class Swan(object): # 天鹅类 def fly(self): print("天鹅在空中翱翔") class Plane(object): # 飞机类 def fly(self): print("飞机隆隆地起飞了") def fly(obj): # 实现飞的功能函数 obj.fly() duck = Duck() fly(duck) swan = Swan() fly(swan) plane = Plane() fly(plane) ===运行结果:=================================================================================== 鸭子沿着地面飞起来了 天鹅在空中翱翔 飞机隆隆地起飞了
2. 对象所属的类之间有继承关系(应用更广)
class gradapa(object): def __init__(self,money): self.money = money def p(self): print("this is gradapa") class father(gradapa): def __init__(self,money,job): super().__init__(money) self.job = job def p(self): print("this is father,我重写了父类的方法") class mother(gradapa): def __init__(self, money, job): super().__init__(money) self.job = job def p(self): print("this is mother,我重写了父类的方法") return 100 #定义一个函数,函数调用类中的p()方法 def fc(obj): obj.p() gradapa1 = gradapa(3000) father1 = father(2000,"工人") mother1 = mother(1000,"老师") fc(gradapa1) #这里的多态性体现是向同一个函数,传递不同参数后,可以实现不同功能. fc(father1) print(fc(mother1)) ===运行结果:=================================================================================== this is gradapa this is father,我重写了父类的方法 this is mother,我重写了父类的方法 100
对比
Java中多态性的表现: 多态性,可以理解为一个事物的多种形态。同样python中也支持多态,但是是有限的的支持多态性,主要是因为python中变量的使用不用声明,所以不存在父类引用指向子类对象的多态体现,同时python不支持重载。在python中 多态的使用不如Java中那么明显,所以python中刻意谈到多态的意义不是特别大。
Java中多态的体现: ① 方法的重载(overload)和重写(overwrite)。 ② 对象的多态性(将子类的对象赋给父类的引用)——可以直接应用在抽象类和接口上 广义上:①方法的重载、重写 ②子类对象的多态性 狭义上:子类对象的多态性(在Java中,子类的对象可以替代父类的对象使用)
更多相关内容 -
【Java面试题】谈谈对Java多态的理解
2021-08-31 14:57:13【Java面试题】谈谈对Java多态的理解 -
JAVA多态图文详解ppt
2018-03-20 16:46:02JAVA多态图文详解ppt,详细通过各种举例介绍JAVA多态的ppt -
Java多态,面向对象编程题demo.zip
2019-12-22 01:11:56这边文章的编程代码:https://blog.csdn.net/qq_41086359/article/details/103650238 Java多态,面向对象编程题 -
Java多态
2022-04-07 19:37:12java多态中关于重载重写、向上和向下转型的一些解析文章目录
1.🧀 回顾继承
那么在上一篇博客Java继承中,我们大致分析了继承的概念如何用父类和子类之间的关系来实现,以及各种应用场景,我们也另外分析了super,protected以及final在其中所起到的作用,并且介绍了组合的概念
那么接着上一篇的继承,我们在这一篇博客中介绍多态。
2.🥗 多态
2.1🥙 多态的概念
多态的概念:通俗来说,就是多种形态,那么在Java中,就是去完成某个行为,当不同的对象去完成时会产生不同的状态和表现。
举两个简单的例子
总的来说:同一件事,发生在不同对象身上,就会产生不同的结果
2.2🥪 多态实现条件
在Java中要实现多态,那么必须要满足以下几个条件,缺一不可:
- 必须在继承体系下
- 子类必须要对父类中的方法进行重写
- 通过父类的引用调用重写的方法
多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。
public class Animal { String name; int age; public Animal(String name,int age){ this.name = name; this.age = age; } public void eat(){ System.out.println(name+"吃饭"); } } public class Cat extends Animal{ public Cat(String name, int age) { super(name, age); } @Override public void eat() { System.out.println(name+"吃鱼"); } } public class Dog extends Animal{ public Dog(String name, int age) { super(name, age); } @Override public void eat() { System.out.println(name+"吃骨头"); } } 分割线/ public class TestAnimal { //编译器在编译代码的时候,并不知道要调用Dog还是Cat中eat的方法 //等程序运行起来之后,形参a引用的具体对象确定后,才知道调用哪个方法 //此时要注意:此处的形参类型必须是父类类型才可以,也就是向上转型 public static void eat(Animal animal){ animal.eat(); } public static void main(String[] args){ Cat cat = new Cat("元宝",2); Dog dog = new Dog("小七",1); eat(cat); eat(dog); } }
运行结果👇
在上述代码中,分割线上方的代码是类的实现者 编写的,分割线下方的代码是类的调用者编写的
当类的调用者在编写eat();这个方法的时候,参数类型为Animal(父类),此时在该方法内部并不知道,也并不关注当前的animal引用指向的是哪个类型(哪个子类)的实例。此时animal这个引用调用eat方法可能会又多种不同的表现(和animal引用的实例对象相关),这种行为就叫做多态
2.3🌮 重写
重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等进行重新编写的一个过程,返回值和形参都不能改变。即外壳不改变,核心重写。
重写的好处在于子类可以根据需要,定义特定的属于子类自己的行为。
也就是说子类能够根据需要来实现父类的方法,又和父类的方法不完全一样,实现自己的特色
2.3.1 🤯 [方法重写的规则]
- 子类在重写父类的方法时,一般必须与父类方法原型一致:修饰符 返回值类型 方法名(参数列表)要完全一致
- JDK7以后,被重写的方法返回值类型可以不同,但是必须是具有父子关系的
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为protected
- 父类被static、private修饰的方法都不能被重写
- 子类和父类在同一个包中,那么子类可以重写父类中的所有方法,除了声明为private和final的方法
- 子类和父类不在同一个包中,那么子类只能够重写父类的 声明为public 和protected的非final方法
- 重写的方法,可以使用 @Override 注解来显式指定。有了这个注解能够帮我们检查这个方法有没有被正确重写。例如不小心讲方法名拼写错了,此时编译器就会发现父类中并没有这个方法,就会编译报错,构不成重写。
2.3.2 🤯 [generate小技巧]
我们右击,点击generate,然后发现这个选项
这样就可以自动生成重写的方法了
2.3.3 🤯 [重写和重载的区别]
区别点 重载(overloading) 重写(override) 参数列表 必须修改 一定不能修改 返回类型 可以修改 一定不能修改 访问限定符 可以修改 不能做出更严格的限制(子类权限大于父类) 即:方法重载式一个类的多态性的表现,而方法重写式子类与父类的一种多态性表现
2.3.4🤯 [重写的设计原则]
对于已经投入使用的类,我们要做到尽量不去进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容,并且添加或者改动新的内容。
例如:若干年前的手机,只能打电话,发短信,来电显示只能显示号码,而今天的手机在来电显示的时候,不仅仅可以显示号码,还可以显示头像,地区等。在这个过程中,我们不应该在原来的老的类上进行修改,因为原来的类可能还有用户在使用,直接修改会影响到这些用户的使用效果,正确做法应该是新建一个手机的类,对来电显示这个方法重写就好了,这样就达到了我们当今的需求
🥫 静态绑定
也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用哪个方法。
典型代表函数重载。
🫔 动态绑定
也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用哪个类的方法
2.4🌯 向上转型和向下转型
2.4.1🍠 向上转型
向上转型:实际上就是创建一个子类对象,将其当成父类对象来舒勇
语法格式: 父类类型 对象名 = new 子类类型();Animal animal = new Cat("元宝",2);
animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换
猫和狗都是动物,因此将子类对象转化为父类引用时合理的,大范围可以囊括小范围,是安全的
🐲【使用场景】- 直接赋值
- 方法传参
- 方法返回
public class TestAnimal { //2.方法传参:形参为父类型引用,可以接受任意子类的 public static void eatFood(Animal a){ a.eat(); } //3.作为返回值:返回任意子类对象 public static Animal buyAnimal(String var){ if("狗"==var){ return new Dog("狗狗",1); }else if("猫"==var){ return new Cat("猫猫",1); }else{ return null; } } public static void main(String[] args){ //1.直接赋值:子类对象赋值给父类对象 Animal cat = new Cat("元宝",2); Dog dog = new Dog("小七",1); eatFood(cat); eatFood(dog); Animal animal = buyAnimal("狗"); animal.eat(); animal = buyAnimal("猫"); animal.eat(); } }
向上转型的优点:让代码实现更加简单灵活
向上转型的缺陷:不能调用到子类特有的方法
2.4.2🥩 向下转型
将一个子类对象经过向上转型之后当成父类对象使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换。
public class TestAnimal { Cat cat = new Cat("元宝",2); Dog dog = new Dog("小七",1); //向上转型 Animal animal = cat; animal.eat(); animal = dog; animal.eat(); //下面这种情况会编译失败 //编译时编译器将animal当作Animal的对象处理 //而Animal类中并没有bark方法,因此编译就会失败 //animal.bark(); //向上转型 //程序可以通过编译,但是运行的时候还是会抛出异常 //因为:animal实际上指向的是狗的对象 //现在要强制还原为猫则无法正常还原,运行时抛出:ClassCastException cat = (Cat)animal; cat.mew(); //animal本来指向的就是狗,因此将animal还原为狗也是安全的 dog = (Dog)animal; dog.bark(); }
向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛出异常。Java中为了提高向下转型的安全性,引入了instanceof,如果该表达式为true,则可以安全转换
public class TestAnimal { public static void main(String[] args){ Cat cat = new Cat("元宝",2); Dog dog = new Dog("小七",1); //向上转型 Animal animal = cat; animal.eat(); animal = dog; animal.eat(); if(animal instanceof Cat){ cat = (Cat)animal; cat.mew(); } if(animal instanceof Dog){ dog = (Dog)animal; dog.bark(); } } }
2.5🍗 多态的优缺点
【使用多态的好处】
1.能够降低代码的“圈复杂度”,避免使用大量的if-else什么叫“圈复杂度”?
圈复杂度是一种描述一段代码复杂程度的方式。
一段代码如果平铺直叙,那么就比较简单容易理解。
而如果有很多的条件分支或者循环语句,就认为理解起来更复杂
因此我们可以简单粗暴的计算一段代码中条件语句和循环语句出现的个数,这个 数就称为“圈复杂度”。如果一个方法的圈复杂度太高,就需要考虑重构
不同公司对于代码的圈复杂度的规范不一样,一般不会超过10例如我们现在需要打印的不是一个形状了,而是多个形状,如果不基于多态,实现代码如下👇
public class DrawShapes { Rect rect = new Rect(); Cycle cycle = new Cycle(); Flower flower = new Flower(); String[] shapes = {"cycle","rect","cycle","rect","flowers"}; public static void main(String[] args) { Rect rect = new Rect(); Cycle cycle = new Cycle(); Flower flower = new Flower(); String[] shapes = {"cycle","rect","cycle","rect","flower"}; for(String shape:shapes){ if(shape.equals("cycle")){ cycle.draw(); }else if(shape.equals("rect")){ rect.draw(); }else if(shape.equals("flower")){ flower.draw(); } } } }
输出结果为👇
如果使用多态,则不必写出这么多的if-else分支语句,代码将更加简单public static void drawShapes(){ Shapes[] shapes = {new Cycle(),new Rect(),new Cycle(), new Rect(),new Flower()}; for(Shapes shape = shapes){ shape.draw(); } }
2.可扩展能力更强
如果要新增一种新的形状,使用多态的方式代码改动成本也比较低class Triangle extends Shape { @Override public void draw(){ System.out.println("▲"); } }
对于类的调用者来说,(drawShapes方法),只要创建一个新类的实例就可以了,改动成本很低。
而对于不用多态的情况,就要把drawShapes中的if-else进行一定的修改,改动成本更高
多态的缺陷:代码运行的效率降低
2.6🍖 避免在构造方法中调用重写的方法
这里介绍一个埋着坑的代码,我们创建两个类,B是父类,D是子类,D中重写了func的方法。并且B的构造方法中调用了func
class B{ public B(){ func(); } public void func(){ System.out.println("B.func()"); } } class D extends B{ private int num = 1; public void func(){ System.out.println("D.func()"+num); } } public class Test { public static void main(String[] args){ D d = new D(); } }
为啥这里的执行结果是0而不是1捏?- 构造D对象的时候,会调用B的构造方法。
- B的构造方法中调用了func方法,此时会触发动态绑定,会调用到D中的func
- 此时D对象自身还没有构造,此时num处在未初始化的状态,值为0
结论:“用尽量简单的方式使对象进入可工作状态”,尽量不要在构造器中调用方法(如果这个方法被子类重写,就会触发动态绑定,但是这个时候子类对象还没有构造完成),可能就会出现一些隐藏的且极难被发现的问题。
多态就介绍到这里
希望能帮到你
感谢阅读~ -
java多态
2022-07-29 21:58:40使用父类作为方法的形参,是Java中实现和使用多态的主要方式之一。向上转型将父类的引用指向子类对象,称为向上转型,自动进行类型转换。多态同一个引用类型,使用不同的实例而执行不同操作。(3)父类的引用指向...一,概念
多态:同一个引用类型,使用不同的实例而执行不同操作
使用父类作为方法的形参,是Java中实现和使用多态的主要方式之一。
二,实现多态的三个要素
(1)继承关系
(2)子类重写父类方法
(3)父类的引用指向子类的对象
三,多态优点
1. 消除类型之间的耦合关系
2. 可替换性
3. 可扩充性
4. 接口性
5. 灵活性
6. 简化性
四,子类到父类的转换(向上转型)
语法:
向上转型语法: <父类型> <引用变量名> = new <子类型>();
Pet pet = new Dog;
向上转型:将父类的引用指向子类对象,称为向上转型,自动进行类型转换
转换时的规则:
此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,不是父类的方法
此时通过父类引用变量无法调用子类特有的方法
五,子类到父类的转换(向下转型)
语法:Penguin png = (Penguin) pet;
必须转换为父类指向的真实子类类型
向下转型:将一个指向子类对象的父类引用赋值给一个子类的引用,称为向下转型,此时必须进行强制类型转换。向下转型可能会出现类型转换异常ClassCastException。
六,Instanceof运算符
1.语法: 对象名 instanceof 类或接口
2.使用经验:
(1)使用instanceof运算符时,对象的类型必须和instanceof的第二个参数所指定的类或接口在继承树上有上下级关系,否则会出现编译错误。
(2)instanceof通常和强制类型转换结合使用
七,总结:
-
Java多态的内存机制
2020-12-22 17:22:431:java面向对象特征:抽象,封装,继承,多态。 抽象: 封装: 继承: 多态: 写一个类,来完成以上所包含的抽象,封装,继承内容 class LaoYin extends Thread implements ... -
java多态例子,java多态代码实例
2021-02-26 08:45:48下面要给大家分享的是一个多态经典案例,一起来看看这个java多态简单例子吧。/*多态的好处:提高了代码的维护性和扩展性;弊端:父类不能使用子类的特有功能。要用子类的特有功能,可以:A:创建子类对象,调用方法...下面要给大家分享的是一个多态经典案例,一起来看看这个java多态简单例子吧。/*多态的好处:提高了代码的维护性和扩展性;
弊端:父类不能使用子类的特有功能。
要用子类的特有功能,可以:
A:创建子类对象,调用方法即可(不合理,太占内存);
B:把父类的引用强制转换为子类的引用(向下转型);
向上转型:Fu f = new Zi();
向下转型:Zi z = (Zi) f;//要求该f必须是转换为Zi的。
*/
class Animal
{
public void eat()
{
System.out.println("吃饭");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("狗吃肉");
}
public void lookDoor()
{
System.out.println("狗看门");
}
}
class Cat extends Animal
{
public void eat()
{
System.out.println("猫吃鱼");
}
public void playGame()
{
System.out.println("捉迷藏");
}
}
public class DuoTaiTest
{
public static void main(String[] args)
{
//定义为狗
Animal a = new Dog();
a.eat();
System.out.println("------------");
//还原成狗
Dog d = (Dog) a;
d.eat();
d.lookDoor();
System.out.println("-------------");
//变成猫
a = new Cat();
a.eat();
System.out.println("-------------");
//还原成猫
Cat c = (Cat) a;
c.eat();
c.playGame();
}
}
运行的结果
上面这个简单的java多态举例,你都仔细的看了吗?你还想了解更多的java经典实例吗?请继续关注奇Q工具网的java实例栏目来了解吧。
推荐阅读:
-
Java多态中的动态绑定与静态绑定
2021-01-21 16:57:15大家可能都知道Java面向对象的三大特性,封装,继承,多态,其中动态绑定就与多态有关,那什么是动态绑定呢? 1.动态绑定(auto binding):也叫后期绑定,在运行时,虚拟机根据具体对象的类型进行绑定,或者说是... -
java 多态练习
2022-03-01 14:42:54文章目录java 多态练习一、题目:二、思路:三、代码: java 多态练习 一、题目: 编写程序实现饮料购买: 编写程序,接收用户输入的信息,选择购买的饮料。 可供选择的饮料有:咖啡、矿泉水和可乐。 其中,... -
Java 多态
2021-03-09 09:03:24一、多态定义多态就是指对象的多种形态。一个是引用的多态;一个是方法的多态。1、引用多态当我们在写面向对象程序的时候,一般父类的引用可以指向本类的对象。Animal a = new Animal(); //a是父类的引用指向的是本... -
Java多态的讲解
2017-07-01 20:10:36Java多态的讲解 -
java多态练习题
2018-04-21 17:52:18java多态、继承练习题,包含题目与答案,............................................................................................................ -
java 多态
2020-05-19 13:43:02java 多态 -
Java多态的详解
2022-01-18 21:57:31Java多态存在的条件: 1.有继承关系 2.子类重写父类方法 3.父类引用子类对象 注意一点: 多态指的是方法的多态,属性没有多态这一说 多态可以实现动态编译,增强可扩展性 新建Application 类 package Demo02; ... -
什么是java多态?java多态的使用
2021-02-12 08:56:09本篇文章给大家带来的内容是什么是java多态?java多态的使用,通过游戏中的一些功能带你掌握多态的使用。下面由动力节点java学院小编为大家一一介绍什么是java多态及java多态的使用。希望对大家有帮助。为什么要使用... -
什么是Java多态?如何实现Java多态?
2021-06-29 10:54:20java多态这个概念在同学们深入学习java的时候就会被提出,很多同学并不知道是什么意思,如何实现。今天小千就来给大家介绍一下什么是java多态和java如何实现多态。 什么是多态? 指允许不同类的对象对同一消息做出... -
java多态调用
2022-04-30 16:41:25概念:多态是什么它就相当于区别对待,比如买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人买票时是优 先买票。再者就是再举个详细的例子: 最近为了争夺在线支付市场,支付宝年底经常会做... -
Java多态详解
2022-04-21 09:52:05基本介绍1.1 多态的概念1.2 对象的多态1.3 入门案例2. 具体细节2.1 向上转型2.2 向下转型2.3 instanceOf 比较操作符3. 实现技术:动态绑定4. 应用4.1 多态数组4.2 多态参数5. 多态的优点 1. 基本介绍 1.1 多态的... -
java有关多态的例题分享,java多态面试题
2021-02-12 11:16:51下面要给大家分享的是几个比较经典也很简单的java多态例题,感兴趣的小伙伴可以一起来通过下面的文章了解一下,对于java面试还是很有帮助的呢。1、多态分类多态分成了2种,一个是编译时多态,另外一个是运行时多态。... -
Java多态实现原理
2021-06-03 16:06:38Java多态实现原理的大致过程:首先是Java编译器将Java源代码编译成class文件。在编译过程中,会根据静态类型将调用的符号引用写到class文件中。在执行时,JVM根据class文件找到调用方法的符号引用,然后在静态类型的... -
Java多态面试题汇总含答案
2022-03-26 11:07:04本文为大家整理汇总了,近年来比较常见且典型的Java多态面试题。当然,本次对面试题的总结整理,更加注重大家对于多态知识的掌握,而不仅仅只是对面试的应付。每道面试题后面都会附上相关问题的答案和分析,让大家... -
Java多态练习题
2022-03-14 16:30:191. 关于Java中的多态,以下说法不正确的为( B )。(选择一项) A 多态不仅可以减少代码量,还可以提高代码的可扩展性和可维护性 B. 把子类转换为父类,称为向下转型,自动进行类型转换 C. 多态是指同一个实现... -
java多态简单例子详解
2021-02-27 20:52:11java多态简单例子:首先有一个Animal类,它有Cat,和Dog两个子类;然后在Animal中有个say方法,当Cat调用这个方法的时候输出的是“小猫喵喵喵”,当Dog调用这个方法时,输出的是“小狗汪汪汪”。【相关学习推荐:...