1 final关键字
在Java中final被称为终结器,可以使用final定义类、方法、属性。
1. 使用final定义的类,不能有子类。
2. 使用final定义的方法不允许被子类所覆写。
3. 使用final定义的变量成为常量,常量在定义时必须赋值并且值不能更改。
在开发中使用public static final来定义全局常量。而且常量的标识符必须全部采用大写字母命名。eg:public static final int LEVEL_A=100;
2 多态性
1.1 概念
Java中多态的核心:
- 方法的多态性:
- 方法的重载:同一个方法名称可以根据参数的类型以及个数的不同调用不同的方法体;
- 方法的覆写:同一个父类的方法,可能根据实例化子类的不同也有不同的实现。
- 对象的多态性(前提:方法覆写):
- 【自动】对象的向上转型:父类 父类对象 = 子类实例;
- 【强制】对象的向下转型:子类 子类对象 = (子类) 父类实例;
范例:回顾一个简单程序
代码
class A {
public void print(){
System.out.println("[A] public void print(){}");
}
}
class B extends A{
public void print(){
System.out.println("[B] public void print(){}");
}
}
public class TestDemo {
public static void main(String[] args) {
B b = new B(); // 实例化子类对象
b.print(); // 调用被覆写过的方法
}
}
输出结果
[B] public void print(){}
范例:实现向上转型
代码
class A {
public void print(){
System.out.println("[A] public void print(){}");
}
}
class B extends A{
public void print(){
System.out.println("[B] public void print(){}");
}
}
public class TestDemo {
public static void main(String[] args) {
A a = new B(); // 向上转型
a.print();
}
}
输出结果
[B] public void print(){}
不管是否发生了向上转型,其本质核心还在于:使用的是哪一个子类(new在哪里),调用的方法是否被子类覆写。
向下转型指的是将父类对象变为子类对象,为什么这样做?
当需要使用到子类扩充操作需使用。
范例:实现向下转型
代码
class A {
public void print(){
System.out.println("[A] public void print(){}");
}
}
class B extends A{
public void print(){
System.out.println("[B] public void print(){}");
}
public void funB(){
System.out.println("[B] public void funB(){}");
}
}
public class TestDemo {
public static void main(String[] args) {
A a = new B(); // 向上转型
a.print();
// 此时父类能够调用的施能是自己本类定义好的方法
// 所以并没有B类中的funB()方法,那么只能进行向下转型
B b = (B) a; // 向下转型
b.funB();
}
}
输出结果
[B] public void print(){}
[B] public void funB(){}
不是所有的父类都可以向下转型:如果要发生向下转型之前一定要发生向上转型,否则在转型时会出现:ClassCastException。
先进行判,在进行转型,依靠instanceof关键字来是实现:
- 子类对象 instanceof 类 ,返回的是boolean型数据
范例:instanceof关键字的使用
代码
class A {
public void print(){
System.out.println("[A] public void print(){}");
}
}
class B extends A{
public void print(){
System.out.println("[B] public void print(){}");
}
public void funB(){
System.out.println("[B] public void funB(){}");
}
}
class C extends A {}
public class TestDemo {
public static void main(String[] args) {
A a = new B(); // 实例化父类对象
System.out.println(a instanceof A);
System.out.println(a instanceof B);
if (a instanceof B){ // 避免ClassCastException
B b = (B) a ;
b.funB();
}
}
}
输出结果
true
true
[B] public void funB(){}
这种转换有什么意义?
范例:要求定义一个方法,而这个方法可以接收Person类的所有子类实例,并调用Person类的方法。
代码
class Person {
public void takeoff(){
System.out.println("take off");
}
}
class Student extends Person {
public void takeoff(){
System.out.println("piece");
}
}
class Woker extends Person {
public void takeoff(){
System.out.println("all");
}
}
public class TestDemo {
public static void main(String[] args) {
in(new Student());
in(new Woker());
}
public static void in(Person per){
per.takeoff();
}
}
输出结果
piece
all
对象的向上转型最核心的用途:操作参数统一。
1.2 总结
- 对象多态性实现的核心在于:方法的覆写;
- 通过对象的向上转型可以实现接收参数的统一,向下转型实现子类扩充方法的调用(一般不操作向下转型);
- 两个没有关系的类对象是不能够进行转型的,一定会发生ClassCastException,向下转型会存在安全隐患。