Java--面向对象三大特征多态
概念
多种形态,完成某个行为,当不同的对象去完成时会产生出不同的状态,简而言之,同类型的对象,表现出不同状态及对象的多种形态
其好处是使用父类作为参数,可以接收所有子类对象,体现了多态的扩展性与便利。
代码如下(示例):
父类类型 对象名称 = 子类对象实例;
Fu f = new Zi();
前提:
-
1.存在继承关系
-
2.有父类引用指向子类对象
-
3.子类必须要对父类中方法进行重写
-
4.通过父类的引用调用重写的方法
举例
在这里插入代码片class Teacher extends Person{
@Override
public void show(){
System.out.println("名字为"+this.getName()+"正在教学生读书");
}
}
class Student extends Person{
@Override
public void show(){
System.out.println("名字为"+this.getName()+"正在读书");
}
}
class Person {
private String name;
private int age;
//无参构造
public Person(){};
public Person(String name,int age){
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println(this.name + "正在玩");
}
}
public class Test {
public static void main(String[] args) {
Student s= new Student();
s.setName("小邬");
s.setAge(30);
Teacher t = new Teacher();
t.setAge(25);
t.setName("王老师");
register(t);
register(s);
}
//用来接收类
public static void register(Person p){
p.show();
}
}
多态调用成员的特点
变量调用:编译看左边,运行也看左。
方法调用:编译看左边,运行看右边。
以下代码实现:
``public class Test1 {
public static void main(String[] args) {
//创建对象
Animal a = new Dog();
//调用成员变量:编译看左边,运行也看左边
//编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有,编译失败
//运行看左边:javac编译代码的时候,实际获取的就是左边父类成员变量的值
System.out.println(a.name);
//调用成员方法:编译看左边,运行看右边
//编译看左边:javac编译代码的时候,回看父类中有没有这个方法 有则编译成功,否则编译失败
//运行看右边:实际上运行的是左边的子类的方法
a.show();
//现在会用Animal这个类的 变量 a来调用
//成员变量:在子类的对象中,会把父类的成员变量也会继承下来。父是name 子也是name
//成员方法:如果子类方法进行了重写,那么在虚方法表中会把父类的方法进行覆盖的。
}
}
class Animal{
String name = "动物";
int age;
public void show(){
System.out.println("Animal~~~~~~~~show");
}
}
class Dog extends Animal{
String name = "狗";
@Override
public void show(){
System.out.println("Dog~~~~~~~~show");
}
}
多态的优势和弊端
优势
1.在多态形式下,右边对象可以实现解耦合,便于扩展和维护
-
Person p =new Student();
-
p.work();//业务发生改变时,后续代码不用修改
2.定义方法的时候,使用父类作为参数,可以接收所有子类对象,体现多态的扩展性与便利。
弊端
1.不能调用子类的特有功能
原因:javac 在编译的时候会第一时间在父类中检查是否存在这个功能,没有就会报错。
那该怎么解决呢?
变会子类类型就可以了
Animal a = new Dog();
Dog d = (Dog) a;
然后再调用子类的方法就可以了**,但是注意转换的时候不能瞎转,如果转成其他类型就会报错。
所有上面代码可以写成这种
Animal a = new Dog();
if(a instanceof Dog){
Dog d = (Dog) a;
}
//其次
还可以写成
Animal a = new Dog();
if(a instanceof Dog d)
//这里先判断a是不是Dog类型,是,则强转为Dog类型,并把变量名改为d
//如果不是,则不能强转并且结果是false
这是的instanceof 是一个关键字 判断的是 a 这个变量所指向的对象是不是 Dog 类型 ,否则不能强转;
总结
- 1.多态的优势:方法中,作为父类型作为参数,可以接收所有子类对象
- 2.多态的弊端:不能使用子类的特有功能
- 3.引用数据类型的类型转换:自动类型转换、强制类型转换(可以转换真正的子类类型,调用子类的独有功能)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步