欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > Java 多态/向下转型/instanceof

Java 多态/向下转型/instanceof

2025/2/23 0:42:11 来源:https://blog.csdn.net/m0_74012211/article/details/145148175  浏览:    关键词:Java 多态/向下转型/instanceof
1. 多态
1.1 概述

多态:事务的不同形态,如 动物,其有多种形态:猫,狗之类的;

1.2 使用方法

虚拟方法(父类被重写的方法在多态中叫做虚拟方法)调用:

父类引用指向子类对象(子类对象赋给父类引用),

即 ” 编译看左边,执行看右边“;

以下是虚拟方法与正常方法的简单对比:

正常方法:

Animal a = new Animal ();

虚拟方法:

Animal a = new Dog;

1.3 使用前提

1. 面向对象的继承性;

2. 重写父类方法;

3. 对象的多态性只适用于方法,不适用于属性,可认为属性没有被重写;

以下是关于动物,猫与狗三类结合多态性的案例:

/**动物类*/
public class Animal {int age;public Animal(){};public void eat(){System.out.println("动物需要补充能量。");}public void sleep(){System.out.println("动物需要睡觉。");}
}
/**狗狗类*/
class Dog extends Animal{@Overridepublic void eat(){System.out.println("狗爱吃骨头!");}@Overridepublic void sleep(){System.out.println("狗闭着眼睛睡觉!");}public void type(){System.out.println("汪星人最可爱的啦!");}
}
/**猫猫类*/
class Cat extends Animal{@Overridepublic void eat(){System.out.println("猫爱吃鱼!");}@Overridepublic void sleep(){System.out.println("猫躺着睡觉!");}public void type(){System.out.println("猫猫也很可爱的啦!");}
}
class AnimalTest{public static void main(String[] args) {
//        创建动物的对象Animal an = new Animal();an.eat();an.sleep();
//        创建狗狗的对象Dog d = new Dog();d.eat();d.sleep();System.out.println("=====================");
//        多态:事物的不同形态;如 动物 可以是 猫,可以是 狗,也可以是其他Animal a = new Dog();
//        使用:1. 父类引用指向子类对象(子类对象赋给父类引用)
//              2. 编译看左边,eat/sleep 方法父类中创建过,
//                 执行看右边:但执行的是子类重写的方法;a.eat();a.sleep();
//        报错:type 是子类独有的,不符合 “编译在左边”,不符多态的使用,因此会报错
//        a.type();}
}
2. 多态的体现

简而言之,多态的使用体现在将子类对象赋给父类,

通过形参为父类,使用匿名对象的方法,避免为多个对象重载,

进而调用不同子类的重写方法,实现不同的功能,

以此降低代码的冗余,提高代码的复用性;

public class multipleTypePeople {private String name;private int age;
//    构造方法public multipleTypePeople(){}public multipleTypePeople(String name,int age){this.age = age;this.name = name;}
//    set/get 方法public void setName(String name){this.name = name;}public String getName(){return name;}public void setAge(int age){this.age = age;}public int getAge(){return age;}
//    方法public void eat(){System.out.println("吃饭长身体!");}public void sleep(){System.out.println("睡眠不足有害身体健康!");}
}
class teacher extends multipleTypePeople{@Overridepublic void eat(){System.out.println("教师也很累!");}@Overridepublic void sleep(){System.out.println("教师睡眠不足!");}
}
class Student extends multipleTypePeople{@Overridepublic void eat(){System.out.println(" 学生也累啊!");}@Overridepublic void sleep(){System.out.println("学业压力也很大!");}
}
class mulTest{public static void main(String[] args) {
//        multipleTypePeople mt = new teacher();mulTest mt = new mulTest();mt.func(new teacher());//mulTest mt = new teacher();mt.func(new Student());//mulTest mt = new student();// 避免为多个对象重载,降低代码的冗余,提高代码的复用性
//        System.out.println("=======================");
//        teacher t = new teacher();
//        t.eat();
//        t.sleep();
//        System.out.println("=======================");
//        Student s = new Student();
//        s.eat();
//        s.sleep();}public void func(multipleTypePeople mt){//形参为父类,使用匿名对象的方法mt.eat();mt.sleep();}
}

 

3. 向下类型转换

以上多态的使用,均属于向上类型转换:

如 Animal a = new Dog ;

将范围小的 Dog 类赋值给 范围大的 Aniaml 类;

3.1 作用

解决无法调用子类特有的方法或属性的问题

情景:如下动物类,狗类以及测试类。

通过子类对象赋给父类引用,

发现无法通过对象调用子类特有的属性和方法;

因为有了对象的多态性之后,内存虽然加载了子类的结构,

但对象声明为父类类型,只能调用父类的属性和子类的重写方法,

无法调用子类特有的的结构;

class reAnimal {int age;public reAnimal(){};public void eat(){System.out.println("动物需要补充能量。");}public void sleep(){System.out.println("动物需要睡觉。");}
}
class reDog extends reAnimal{//    特有的属性public String name;@Overridepublic void eat(){System.out.println("狗爱吃骨头!");}@Overridepublic void sleep(){System.out.println("狗闭着眼睛睡觉!");}//    特有的方法public void type(){System.out.println("汪星人最可爱的啦!");}public void color(String color){System.out.println("狗狗的颜色是" + color);}
}
class reAnimalTest{public static void main(String[] args) {reAnimal ra = new reDog();
//      无法调用子类特有的方法或属性;因为编译时,rat 是 reAnimal 类,只能调用父类的结构ra.name = "团子";ra.color("黄色");}
}

3.2 格式

子类 子类对象 = ( 子类 )父类对象

理解:

赋值运算符两边数据类型要么相同,

要么右边数据类型可以自动上升为左边,

显然,向下类型转换不能完成,

因此使用 ( ),实现强制转换;

4. instanceof 关键字
4.1 引入

使用向下类型转换需要强制类型转换,

强制类型转换总伴随缺点,

对其他子类再实现向下类型转换

就会出现异常;

如下:对狗向下类型转换之后,再对猫实现向下类型转换,就会发生异常;

class reAnimal {int age;public reAnimal(){};public void eat(){System.out.println("动物需要补充能量。");}public void sleep(){System.out.println("动物需要睡觉。");}
}
class reCat extends reAnimal{@Overridepublic void eat(){System.out.println("猫爱吃鱼!");}@Overridepublic void sleep(){System.out.println("猫躺着睡觉!");}public void type(){System.out.println("猫猫也很可爱的啦!");}
}
class reDog extends reAnimal{//    特有的属性public String name;@Overridepublic void eat(){System.out.println("狗爱吃骨头!");}@Overridepublic void sleep(){System.out.println("狗闭着眼睛睡觉!");}//    特有的方法public void type(){System.out.println("汪星人最可爱的啦!");}public void color(String color){System.out.println("狗狗的颜色是" + color);}
}
class reAnimalTest{public static void main(String[] args) {reAnimal ra = new reDog();
//      可以调用父类的属性ra.age = 12;
//       向下类型转换reDog rd = (reDog) ra;rd.name = "大黄";rd.color("黄色");
//        缺点:可能出现异常reCat rc = (reCat) ra;rc.eat();}
}

4.2  作用

为避免向下转型出现异常,

在向下转型之前,

常用 instanceof 判断,

结果为 true ,进行向下转型;

结果 为 false , 不进行向下转型;

5. 练习

public class GeoTest {protected String color;protected double weight;protected GeoTest(){}protected GeoTest(String color){this.color = color;this.weight = weight;}public void setColor(String color){this.color = color;}public String getColor(){return color;}public void setWeight(double weight){this.weight = weight;}public double getWeight(){return weight;}public double findArea(){return 0;}
}class Circle extends GeoTest{private double radius;public Circle(){}public Circle(String color,double radius){super(color);this.radius = radius;}public void setRadius(double radius){this.radius = radius;}public double getRadius(){return radius;}@Overridepublic double findArea(){return Math.PI*radius*radius;}
}class MyRectangle extends GeoTest{private double width;private double height;public MyRectangle(){}public MyRectangle(String color,double width,double height){super(color);this.width = width;this.height = height;}public void setWidth(double width){this.width = width;}public double getWidth(){return width;}public void setHeight(double height){this.height = height;}public double getHeight(){return height;}@Overridepublic double findArea(){return width * height;}
}
class GeomeTest{public static void main(String[] args) {GeomeTest get = new GeomeTest();MyRectangle mt = new MyRectangle("白色",10,10);Circle cl = new Circle("紫色",12);get.equalArea(cl,mt);//GeoTest gt1 = new MyRectangle,GeoTest gt2 = new Circleget.displayGeomeArea(cl);//GeoTest gt = new Circleget.displayGeomeArea(mt);//GeoTest gt = new MyRectangle}public void equalArea(GeoTest gt1,GeoTest gt2){System.out.println(gt1.findArea() == gt2.findArea());}public void displayGeomeArea(GeoTest gt){System.out.println(gt.findArea());}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词