【Java】多态性
2024-09-07 08:58:32
多态性
可以理解为一个事物的多种形态。
对象的多态性:父类的引用指向子类的对象。只适用于方法,不适用于属性(编译和运行都看左边)
总结:对于对象的多态性,编译,看左边;运行,看右边。
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
虚拟方法:子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
多态性的使用前提:
- 类的继承关系
- 方法的重写
使用实例:
class Animal{
public void eat(){
System.out.println("动物:进食");
}
public void shout(){
System.out.println("动物:叫");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void shout(){
System.out.println("汪!汪!汪!");
}
public void watchDoor(){
System.out.println("看门");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
public void shout(){
System.out.println("喵!喵!喵!");
}
}
public class Test {
public static void main(String[] args) {
Test test = new Test();
test.func(new Dog());
test.func(new Cat());
}
public void func(Animal animal){//Animal animal = new Dog();
animal.eat();
animal.shout();
}
}
向下转型
public class Person {
String name;
int age;
int id = 1001;
public void eat(){
System.out.println("人:吃饭");
}
public void walk(){
System.out.println("人:走路");
}
}
public class Man extends Person{
boolean isSmoking;
int id = 1002;
public void earnMoney(){
System.out.println("男人负责挣钱养家");
}
public void eat(){
System.out.println("男人多吃肉,长肌肉");
}
public void walk(){
System.out.println("男人霸气的走路");
}
}
有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
p2.name = "Tom";
p2.earnMoney();//无法调用
p2.isSmoking = true;//无法调用
如何调用子类特有的属性与方法呢?
向下转型:使用强制类型转换符。
Man m1 = (Man)p2;
m1.earnMoney();//可以调用
m1.isSmoking = true;//可以调用
使用强转时,可能出现ClassCastException的异常。
Woman w1 = (Woman)p2;
w1.goShopping();//man不能转成woman
此时应该用instanceof来判断是否可以向下转型。
判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先
进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
//编译时通过,运行时不通过
Person p3 = new Woman();
Man m3 = (Man)p3;
//编译通过,运行时也通过
Object obj = new Woman();
Person p = (Person)obj;
//编译不通过
Man m5 = new Woman();
String str = new Date();
Object o = new Date();
String str1 = (String)o;
最新文章
- 10.Pattern 和 Matcher
- 邮箱验证 各种邮箱的smtp
- 【转】【C#】ColorMatrix
- ubuntu16.04 搭建 Mysql服务器
- Tyvj 1030 乳草的入侵
- Class File Editor: Source not found
- css3 盒模型
- mysql触发器使用注意
- 【转】fread函数详解
- 项目Alpha冲刺Day12
- javascript 函数后面有多个小括号f( )( )( )...
- 在微信下载app引导页代码
- 『OpenCV3』Mat简介
- HDU5532 Almost Sorted Array(最长上升子序列 or 瞎搞个做差的数组)
- 在ActiveReports页面报表中显示Google地图
- jfinal如何设置使用哪种模板引擎(视图)
- 【java】AES加密解密|及Base64的使用
- Android Intent 用法全面总结(转载)
- 在asp.net页面上得到Castle容器的实例
- LCD控制器与帧率、刷新率的关系分析
热门文章
- 🔥🔥🔥【已开源】Flutter 腾讯优量汇广告插件,帮助开发者获利 - FlutterAds
- Sentry 开发者贡献指南 - 前端 React Hooks 与虫洞状态管理模式
- Java Record 的一些思考 - 默认方法使用以及基于预编译生成相关字节码的底层实现
- Java面向对象之 接口: [修饰符] interface 接口名 {...};子接口:[修饰符] interface 接口名 extends 父接口,父接口2...{...}
- 访问struts2的action页面出现白板问题
- 大型网站高可用架构之CAP原理
- navicat模型分享方法
- SpringBoot整合quartz框架启动定时任务报错:the given trigger will never fire.
- JAVA获取访问者的内网IP地址
- 【LeetCode】871. Minimum Number of Refueling Stops 解题报告(Python)