关于JAVA继承与多态的那点“事“

序言:在书上刚读到继承与多态时,脑中充满了疑问与困惑,在反复的阅读和实践以后,对这部分才稍稍有了自己的一点见解。这篇文章主要对Java继承和多态进行更为简单通俗的解释,希望能对你能有所帮助。

继承篇

首先来看Java的继承特性,下面笔者主要描述的时父子间的单一继承。

在了解一个新名词之前我们先来理解下它的概念,什么是继承?顾名思义,儿子学会父亲的手艺便称作“继承”,当然,Java的子类可不仅仅指儿子,孙子、重孙子等都属于子类。若按照书上的原话来讲:继承是类之间的“is a”关系,反映出子类是父类的特例。emmm...反正笔者暂时无法理解特例的含义。

总之,将继承理解为子类拥有父类的成员和方法也可。

知道这个特性所表示的含义了,那它是怎样在代码中表现出来呢?那就不得不谈到一个关键词"extends"。看如下代码:

class Dad{}
calss son extends Dad{}

这是声明的两个类,一个名为Dad,另一个名为Son, 我们可以轻松理解Dad是爸爸,Son是儿子,但计算机可不懂这些语言的含义,所以我们要用extends(继承),son extends Dad就是告诉计算机son是Dad的儿子。

好了,现在让我们来试着运用一下:

//先来创建一个父类
class Father{
    String father;
    public int add(int a, int b){
        return a+b;
    }
}
//再来创建一个子类
class Baby extends Father{}

其实这里还有一个小问题,当父类无构造方法或构造方法无需传参时,子类可以直接继承。但当父类有构造方法且需要传参时,需要在子类中也声明同样的构造方法,并使用super方法,如下: 

//先来创建一个父类
class Father{
    int c;
    public Father(int a, int b){
        c = a+b;
    }
    public int add(int a, int b){
        return a+b;
    }
}
//再来创建一个子类
class Baby extends Father{
    public Baby(int a, int b) {
        super(a, b);
    }
}

什么?你问super是什么?我们在学习类与对象的时候应该知道this方法吧,this是用来调用类自身的成员和方法,而super则是调用父类的成员和方法,或者说,你可以将super作为父类的实例化变量。

那基本的继承也就学的差不多了,来试着应用一下吧:

public class Daji_test1 {
    public static void main(String arg[]){
        Baby baby = new Baby();
        baby.add(1, 2);
    }
}
class Father{
    int c;
    public int add(int a, int b){
        System.out.println(a+b);
        return 0;
    }
}
class Baby extends Father{
}

 当然,这只是一个基础的调用,其它的方法就要你自己去多加尝试了。

多态篇

了解了基本的继承之后,我们继续来看的Java多态特性。多态涉及继承的方法重写,方法重写就是在子类中将父类的方法重复一遍,声明与父类保持一致,具体行为可以有所改变。我们先来看一个例子:

/*
创建三个类:
    A是父类
    A_1、A_2均是子类
 */
class A{
    public void print(){
        String s = "";
        System.out.println(s);
    }
}
class A_1 extends A{
    public void print(){
        String s1 = "你好";
        System.out.println(s1);
    }
}
class A_2 extends A{
    public void print(){
        System.out.println("000");
    }
}

图中创建了三个类,A为父类,另外两个为子类。可以看到每个类中都写了同一个方法,但是实现的效果不一样,这便是方法的重写,理解为重复书写不太准确,笔者觉得这更像重新书写。知道了这一概念后我们在来谈谈“多态”。

书上谈到多态时,首先用对初学者较难理解的一段话引入了“上溯造型”的概念,也正是对这段捉摸不透让笔者多次萌生放弃的想法。

刚刚的三个类想必你以有所意会,这时如果我写了这样一个方法对三个类分别进行调用:

public class Daji_test2 {
    public static void main(String arg[]){
        A[] as = new A[3];
        as[0] = new A();
        as[1] = new A_1();
        as[2] = new A_2();
        for ( int i=0; i<3; i++ ){
            as[i].print();
        }
    }
}

把类作为了数组?没错!这便是所谓的“上溯造型”,即父类可以把子类作为对象,当数组类型为父类时,数组中的元素类型可以是任意子类 。

这一段有点绕,举个不太恰当但容易理解的解释:因为Java继承中,子类继承父类的所有:如果父类有一个苹果,则所有子类都有苹果。

这比较容易理解。

但如果这时候某一个子类给了父类一个香蕉,父类有了香蕉,那所有子类也应该都有香蕉,emmm...是不是有点感觉了,这个子类也是一种特殊的父类。

又因为子类的变量和方法相较于父类更加的完善,所以子类转换为父类时是绝对安全的(挖个坑)。

将子类对象引用转换为父类对象引用----称之为"上溯造型"。

可能你还不太理解,或者说完全不理解,这也没关系,我们继续向后看。

如果将刚刚的代码改为这样:

public class Daji_test2 {
    public static void main(String arg[]){
        A as = new A();
        as.print();
    }
}

或者说这样:

public class Daji_test2 {
    public static void main(String arg[]){
        A as = new A_1();
        as.print();
    }
}

聪明的你应该发现了,我两次实例化的as都是父类型的,但在开辟空间的时候(new的时候)却一个指向A,另一个指向A_1,因此在调用方法时,得到的也不同的结果。这便是多态同一类型同一方法不同的状态

这是极其有意思的,如果你仍不理解的话,不妨自己去敲代码试试看。

public class Daji_test2 {
    public static void main(String arg[]){
        A[] as = new A[3];
        as[0] = new A();
        as[1] = new A_1();
        as[2] = new A_2();
        for ( int i=0; i<3; i++ ){
            as[i].print();
        }
    }
}

再看刚刚的代码,是不是对继承和多态又有了一定理解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值