Java阻断继承和向上向下转型

Java阻断继承和向上向下转型,第1张

1、阻断继承

        从Java15开始,允许使用sealed修饰符,并通过permits明确写出能够从该class继承的子类名称。这种sealed类主要用于一些框架,防止继承被滥用。sealed类在Java15中目前是预览状态,要启用它,必须使用参数"--enable-preview"和"--source 15"。

        注:sealed [siːld] adj.封闭的,密封的。permits [pəˈmɪts] n.许可。

// Shape类是一个sealed类,它只允许指定的3个类继承它。
public sealed class Shape permits Rect, Circle, Triangle {
    ... ... 
}
// Rect类在Shape的permits列表中,允许继承Shape
public final class Rect extends Shape {
    ... ...
}
// Ellipse类并未出现在Shape的permits列表中,继承Shape会报错
public final class Ellipse extends Shape {
    ... ...
}

        正常情况下,只要某个class没有定义final修饰符,那么任何类都可以从该class继承。当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。

2、向上转型和向下转型

(1)向上转型

        如果Student类是从Person继承下来的,一个引用类型为Person的变量,它是可以指向Student类型的实例。这种把一个子类类型安全地变为父类类型的赋值,被称为向上转型(upcasting)。

Student s = new Student();
Person p = new Person();
Person p = new Student();  // Person类型变量是可以指向Student类型实例

        注意:继承树Student -> Person ->Object,可以把Student类型转型为Person,或者更高层次的Object。

(2)向下转型

        和向上转型相反,如果把一个父类类型强制转型为子类类型,就是向下转型(downcasting)。

Person p1 = new Student(); // 向上转型,OK
Person p2 = new Person();
Student s1 = (Student) p1;  // 向下转型, OK
Student s2 = (Student) p2;  //  向下转型,Error

        Person类型p1实际指向Student类型实例,Person类型p2实际指向Person类型实例。

        在向下转型的时候,把p1转型为Student会成功,因为p1确实指向Student实例。

        在向下转型的时候,把p2转型为Student会失败,因为p2的实际类型是Person,不能把父类变为子类,因为子类功能比父类功能多,多的功能无法凭空变出来。

        总结:向下转型可能会失败,失败的时候,Java虚拟机会报classCaseException错误。

(3)instanceof *** 作符

        为了避免向下转型出错,Java提供了instanceof *** 作符,用于判断实例的类型。

Person p = new Person();
System.out.println(p instanceof Person); // true
System.out.println(p instanceof Student); // false

Person p = new Student();
if (p instanceof Student) {
    // 只有判断成功才会向下转型:
    Student s = (Student) p; // 一定会成功
}

        从Java14开始,判断instanceof后,可以直接转型为指定变量,避免再次强行转型。

Object obj = "hello";

if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.toUpperCase());
}
// Java14写法,和上面等价,这种使用instanceof的写法更加简洁。
if (obj instanceof String s) {
            // 可以直接使用变量s:
            System.out.println(s.toUpperCase());
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/720975.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存