Java抽象类小记,踩踩多态的坑!

今天学习写MapReduce的时候,遇到下面这样的一个代码:

如图所见,context.getInputSplit() 返回的是 InputSplit 类型,而 InputSplit 是父类,FileSplit 是子类,我们知道,Java里,父类不能够强制转换成子类,那为什么这里又可以呢?

带着这个疑问,我做了一个小实验,详见下面代码:

Father类:

public abstract class Father {

    public void sayFather() {
        System.out.println("Father");
    }

    public abstract  void abstractSayFather();
}

Son类: 

public abstract class Son extends Father{

    @Override
    public void sayFather(){
        System.out.println("The son say Father");
    }

    public void saySon(){
        System.out.println("son!!");
    }

    //实现父类抽象方法
    @Override
    public void abstractSayFather() {};

    public GrandSon getGrandSon() {
        GrandSon g = new GrandSon();
        return g;
    }

}

Brother类:

public class Brother extends  Father{
    public void sayBrother() {
        System.out.println("say Brother !!!!");
    }

    @Override
    public void abstractSayFather() {
        System.out.println("I am Brother ,This fun is extends Father!!!");
    };
}

OtherPeople类:

public abstract class OtherPeople {

    public void sayOtherPeople() {
        System.out.println("OtherPeople !!!");
    }

}

GrandSon类:

public class GrandSon {

    public void sayGrand() {
        System.out.println("Grand Son !!");
    }

}

主程序,运行的坑和注释都写在代码里面了,请详细看:

public class TestMain {

    private Father f4;
    private Son s4;
    private GrandSon g4;

    //字类可以强制转换成父类
    public void demo1(Father f4) {
        //注意这里!父类可强制转换成子类,而且!s4, , f4 并没有实例化!!!
        this.s4 = (Son) f4;
        System.out.println("1 ----------------------------");
        //注意这里!这里s4虽然是从父类转换过来,但是不可以使用到子类的方法!!
        this.s4.saySon();
    }

    public void run() {
        //Son 为抽象类,但是这里却可以 new Son() 但是一定要加大括号,括号里面可以重写方法,也可以什么都不写,如下面这里
        Father f1 = new Son() {
            @Override
            public void sayFather() {
                System.out.println("执行sayFather方法:");
                super.sayFather();
            }
        };
        f1.sayFather();
        System.out.println(f1.toString()); //打印结果为 TestMain$1@1b6d3586
        System.out.println("2 ---------------------------------------");
        //大括号里面什么都不写
        Father f2 = new Son(){};  // 这里并没有报错
        Father f3 = new Son(){
            public void sayFatherFun2() {
                System.out.println("在这里,可以甚至可以新建一个新的函数");
                System.out.println("say father function 2 !!!!");
            }
        };
        //这里报错,虽然上面写了 sayFatherFun2 方法,但是并不能够使用,只可以使用Son类的方法
        //f3.sayFatherFun2;
        System.out.println(f2.toString()); //打印结果类似为 TestMain$2@1b6d3586
        System.out.println(f3.toString()); //打印结果类似为 TestMain$3@4554617c
        System.out.println("3 ---------------------------------------");
        //注意这里!f2 为父类 Father,但是可以强制转换成子类 son 并且可以直接调用子类 son 的方法 getGrandSon() !!!! 对g4进行了实例化!!!!
        this.g4 = ((Son)f3).getGrandSon();  // 正常执行
        //运行报错,因为 在 main 方法里 f4 已经是 Brother 的实例了!!!
        //this.g4 = ((Son)f4).getGrandSon();
        this.g4.sayGrand();
        System.out.println(this.g4.toString());  //可以见到打印出 GrandSon的实例
        System.out.println("4 ---------------------------------------");
        //报错,OtherPeople为毫不相干的类!!!
        //((OtherPeople)f4).sayOtherPeople();
    }

    public static void main(String[] args) {
        TestMain test = new TestMain();
        //下面代码执行异常!报空指针异常!!因为 test.f4 还没有实例!!
        //test.demo1(test.f4);

        //执行正常 子类转成父类,只能够用父类的方法了
        test.f4 = new Brother();
        //执行正常
        test.f4.abstractSayFather();
        //执行异常,test.f4 已经实例化了,虽然引用是Fahter,但是实例是 Brother,不能够强制转成son类!!!
        //test.demo1(test.f4);

        test.run();
    }
}

运行结果:

 Java多态的坑!!!多踩踩!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值