1. 多态中成员变量的使用特点
【父类】
public class Animal {
int age = 10;
public void bark() {
System.out.println("Animal叫...");
}
public void show() {
System.out.println(age);
}
}
【子类】
public class Cat extends Animal {
int age = 20;
@Override
public void bark() {
System.out.println("喵喵喵...");
}
public void show() {
System.out.println(age);
}
}
【主函数】
public class Test {
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(cat.age); // 20
cat.bark(); // 喵喵喵...
cat.show(); // 20
Animal animal = new Dog();
System.out.println(animal.age); // 10
animal.bark(); // 喵喵喵...
animal.show(); // 20
}
}
从中可以看出多态中使用成员变量的一些特点:
- 直接通过对象访问成员变量,看等号左边是谁就优先用谁,没有则向上找,如
cat.age=20
以及animal.age=10
- 间接通过成员方法访问成员变量,看该方法属于谁就优先用谁,没有则向上找,如
cat.show()
和animal.show()
2. 多态中成员方法的使用特点
【父类】
public class Father {
int num = 10;
public void showNum(){
System.out.println(num);
}
public void method(){
System.out.println("父类方法...");
}
public void methodFather(){
System.out.println("父类特有方法...");
}
}
【子类】
public class Son extends Father{
int num = 20;
int age = 16;
@Override
public void showNum() {
System.out.println(num);
}
@Override
public void method() {
System.out.println("子类方法...");
}
public void methodSon(){
System.out.println("子类特有方法...");
}
}
【主函数】
public class Test {
public static void main(String[] args) {
Father obj = new Son();
obj.method(); // 父子都有,优先用子
obj.methodFather(); // 子类没有父类有,向上找到父类
}
}
针对多态中的成员方法,记住一句话:编译看左边,运行看右边
3. 多态综合示例
【相关类】
class A {
public void show(D d) {
System.out.println("A and D");
}
public void show(A a) {
System.out.println("A and A");
}
}
class B extends A {
public void show(B b) {
System.out.println("B and A");
}
public void show(A a) {
System.out.println("B and A");
}
}
class C extends B {}
class D extends B {}
【测试类】
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
// 下面输出会使是什么?
a1.show(b); // A and A ①
a1.show(c); // A and A ②
a1.show(d); // A and D ③
a2.show(b); // B and A ④
a2.show(c); // B and A ⑤
a2.show(d); // A and D ⑥
b.show(b); // B and A ⑦
b.show(c); // B and A ⑧
b.show(d); // A and D ⑨
}
}
- ①②③比较好理解,就在A类中找函数,不符合就向上转型
- ④⑤⑥是由于
A a2 = new B()
,a2
包含的方法有A
类中的show(D d)
、B
类中重写的show(A a)
- ⑦⑧⑨是由于
B b = new B()
,b
包含的方法有A
类中的show(D d)
、B
类中重写的show(A a)
以及B
类本身的特有方法show(B b)
4. instanceof
instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:
boolean result = obj instanceof Class
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。
4.1 obj 必须为引用类型,不能是基本类型
int i = 0;
System.out.println(i instanceof Integer);//编译不通过
System.out.println(i instanceof Object);//编译不通过
instanceof 运算符只能用作对象的判断。
4.2 obj 为 null
System.out.println(null instanceof Object);//false
一般我们知道Java分为两种数据类型,一种是基本数据类型,有八个分别是
byte
、short
、int
、long
、float
、double
、char
、boolean
,一种是引用类型,包括类,接口,数组等等。而Java中还有一种特殊的null
类型,该类型没有名字,所以不可能声明为null
类型的变量或者转换为null
类型,null
引用是null
类型表达式唯一可能的值,null
引用也可以转换为任意引用类型。我们不需要对null
类型有多深刻的了解,我们只需要知道null
是可以成为任意引用类型的特殊符号,但是其不是任何类的实例。
4.3 obj 为 class 类的实例对象
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);//true
常规语法
4.4 obj 为 class 接口的实现类
了解Java 集合的,我们知道集合中有个上层接口 List
,其有个典型实现类 ArrayList
,所以我们可以用instanceof
运算符判断 某个对象是否是List
接口的实现类,如果是返回true
,否则返回false
ArrayList arrayList = new ArrayList();
System.out.println(arrayList instanceof List);//true
4.5 obj 为 class 类的直接或间接子类
我们新建一个父类 Person.class,然后在创建它的一个子类 Man.class
public class Person {
}
// ---------------------------------------------------
public class Man extends Person{
}
【测试】
Person p1 = new Person();
Person p2 = new Man();
Man m1 = new Man();
System.out.println(p1 instanceof Man);//false
System.out.println(p2 instanceof Man);//true
System.out.println(m1 instanceof Man);//true
注意第一种情况,
p1 instanceof Man
,Man
是Person
的子类,Person
不是Man
的子类,所以返回结果为false
。
4.6 问题
前面我们说过编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。
看如下例子:
Person p1 = new Person();
System.out.println(p1 instanceof String);//编译报错
String
是final
类,不可继承,哪来的instance of String