多态可以用一句话来描述:父类的引用指向子类的对象。
Father类、Son类,其中Father类是Son类的父类
Father father = new Son();//就是多态的一种写法
多态的优点:
多态的使用可以让咱们的代码变得更加灵活,简洁,具有普适性
多态存在的三个必要条件:
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
父类引用指向子类对象:Parent p = new Child();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
package com.qfedu.app1;
//父类
class A{
int ageA;
public void testA(){
System.out.println("我是A的方法");
}
}
//子类
class B extends A{
int ageB;
public void testB(){
System.out.println("我是B的方法");
}
}
public class Demo1 {
public static void main(String[] args) {
A a = new B();//父类的引用指向子类的对象
a.ageA=2;//使用多态后,只能调用父类的属性和方法,不能调用子类的东西
a.testA();
//结果打印为:我是A的方法
}
}
向上转型和向下转型
向上转型:通过子类的对象(小范围)去实例化父类的对象(大范围),属于自动转换【父类的引用指向子类的对象】小范围转为大范围 是自动转的
向下转型:通过父类的对象(大范围)去实例化子类的对象(小范围),属于强制转换
向上转型:
package com.boke.app1;
class A {
public void test(){
System.out.println("A:test");
}
}
class B extends A {
@Override
public void test() {
System.out.println("B:test");
}
}
public class Test {
public static void main(String[] args) {
A a = new B();//向上转型,父类引用指向子类的对象。
//通过子类去实例化父类
a.test();
//意义:当我们需要对方法进行传参数的时候,这个参数可以是父类的对象,但是传真实的参数的时候,直接传子类的对象即可
}
}
向下转型:
package com.boke.app1;
class A1 {
public void test(){
System.out.println("A:test");
}
}
class B1 extends A1 {
@Override
public void test() {
System.out.println("B:test");
}
public void funcB () {
System.out.println("funcB");
}
}
class C1 extends A1 {
@Override
public void test() {
System.out.println("C:test");
}
public void func() {
System.out.println("funC");
}
}
public class Test1 {
public static void main(String[] args) {
A1 a1 = new A1();
func(a1);//打印A:test
}
public static void func (A1 a1) {
a1.test();
if (a1 instanceof B1) {
//子类 子类变量名字 = (子类)父类对象;
B1 b1 = (B1)a1;//强制转换 获得子类特有的方法,要获取子类对象
b1.funcB();
} else if(a1 instanceof C1){
C1 c1 = (C1) a1;
c1.func();
}
}
}
总结:
父转子,需要强制类型转换,目的是为了调用子类独有的方法
子转父,自动转换,啥也不需要,但是不可以调用子类独有的方法