1.多态性
1.概念
向上转型(自动完成)
子类转变成父类
父类 父类对象 = 子类实例化对象
向下转型(强制)
父类转变成子类,必须首先进行向上转型
子类 子类对象 = (子类)父类实例化对象
2.子类对象向上转型
//本程序是多态性的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
public class TestPol
{
public static void main(String[] args)
{
B b = new B(); //定义子类的实例化对象
A a = b; //子类对象向上转型
a.fun1(); //此方法被子类覆写了,输出的是覆写的
a.fun2(); //此方法被子类覆写了,输出的是覆写的
}
}
说明:向上转型使用方法都是子类覆写过的方法。
注意:在A中只能看到两个方法,在B看到三个方法,转型之后,因为操作的是父类,所以无法找到子类中定义的新方法。
//本程序是多态性的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
public class TestPol
{
public static void main(String[] args)
{
B b = new B(); //定义子类的实例化对象
A a = b; //子类对象向上转型
a.fun1(); //此方法被子类覆写了,输出的是覆写的
a.fun3(); //新方法
}
}
错误信息提示:
TestPol.java:31: 错误: 找不到符号 a.fun3(); //新方法 ^ 符号: 方法 fun3() 位置: 类型为A的变量 a |
3.父类对象向下转型
//本程序是多态性的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
public class TestPol
{
public static void main(String[] args)
{
B b = new B(); //定义子类的实例化对象
A a = b; //子类对象向上转型
B c = (B) a; //父类向下转型
c.fun1(); //此方法被子类覆写了,输出的是覆写的
c.fun2(); //新方法
}
}
在类B中存在三个方法,全部可以调用。
注意:进行向下转型操作时,
//本程序是多态性的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
public class TestPol
{
public static void main(String[] args)
{
//B b = new B(); //定义子类的实例化对象
//A a = b; //子类对象向上转型
A a = new A(); //定义父类的实例化对象
B c = (B) a; //父类向下转型
c.fun1(); //此方法被子类覆写了,输出的是覆写的
c.fun2(); //新方法
}
}
如果不先进行向上操作的话,会有错误信息。
Exception in thread "main" java.lang.ClassCastException: A cannot be cast to B at TestPol.main(TestPol.java:31) |
4.对象多态性的应用
要求设计一个方法,能够调用A类任意子类的对象。
//本程序是多态性的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
class C extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类C覆写的fun1方法");
}
public void fun4()
{
System.out.println("这是类C的fun4方法");
}
}
public class TestPol
{
public static void main(String[] args)
{
fun(new B());
fun(new C());
}
public static void fun(B b)
{
b.fun1();
}
public static void fun(C c)
{
c.fun1();
}
}
如果子类过多,无法完成这一目标,可以使用对象多态行完成。
//本程序是多态性的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
class C extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类C覆写的fun1方法");
}
public void fun4()
{
System.out.println("这是类C的fun4方法");
}
}
public class TestPol
{
public static void main(String[] args)
{
fun(new B());
fun(new C());
}
public static void fun(A a)
{
a.fun1();
}
}
2.instanceof 关键字
在对象转型中经常使用
1.概念
在java中使用instanceof判断一个对象到底是哪个类的实。
对象 instanceof 类 ---------------->他返回的是boolean型
//本程序是isntanceof的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
public class TestInstanceOf
{
public static void main(String[] args)
{
B b = new B(); //定义子类的实例化对象
A a = b; //向上转型
A a2 = new A();
System.out.println(a instanceof A);
System.out.println(a instanceof B);
System.out.println(a2 instanceof A);
System.out.println(a2 instanceof B);
}
}
1.作用
如果传入的是B类的实例,调用fun3,如果是C类调用fun4
//本程序是isntanceof的测试
class A //定义类A
{
public void fun1() //定义类A的fun1方法
{
System.out.println("这是类A的fun1方法");
}
public void fun2()
{
this.fun1();
}
}
class B extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类B覆写的fun1方法");
}
public void fun3()
{
System.out.println("这是类B的fun3方法");
}
}
class C extends A //类B继承类A
{
public void fun1() //覆写fun1方法
{
System.out.println("这是类C覆写的fun1方法");
}
public void fun4()
{
System.out.println("这是类C的fun4方法");
}
}
public class TestInstanceOf
{
public static void main(String[] args)
{
fun(new B());
fun(new C());
}
public static void fun(A a)
{
if (a instanceof B)
{
A a1 = a; //现在a是子类,先进行向上转换
B b = (B) a1; //父类向下转换
b.fun3();
}
if (a instanceof C)
{
A a1 = a; //现在a是子类,先进行向上转换
C c = (C) a1; //父类向下转换
c.fun4();
}
}
}
注意:开发中,向下转型操作要进行验证,确保不会出问题。
如果要增加新的子类,则要修改fun方法,这样程序就失去了灵活性。所以程序设计重点放在父类上。只要足够合理,开发非常方便。
一个类永远不要去继承已经实现好了的类,只能继承抽象类或实现接口。