JAVA基础再回首(六)——父与子的继承、super关键字、方法重写、方法重载

原创 2016年08月02日 22:10:10

JAVA基础再回首(六)——父与子的继承、super关键字、方法重写、方法重载

不墨迹,才是时间管理的最大利器,学无止境。

继承

首先我们来学习继承的概述

  • 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
  • 通过extends关键字可以实现类与类的继承
    • 格式:class 子类名 extends 父类名 {}
  • 单独的这个类称为父类,基类或者超类;这多个类可以称为子类或者派生类。
  • 有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。

以前我们没有学习继承之前,是这样定义一个类和类中的方法的。

//使用继承前
class Student {
    public void eat() {
        System.out.println("吃饭");
    }
    public void sleep() {
        System.out.println("睡觉");
    }
}

class Teacher {
    public void eat() {
        System.out.println("吃饭");
    }
    public void sleep() {
        System.out.println("睡觉");
    }
}

通过观察我们可以学生类和老师类他们都有共同的方法就是吃和睡,既然老司机已经带我们上路了,那么我们就可以改进上面的代码,将相同的成员抽取到一个类中,争取早日成为一名老司机。

//使用继承后
//首先我们定义一个人类,因为老师、学生都属于人,都要吃饭和睡觉
class Person {
    public void eat() {
        System.out.println("吃饭");
    }
    public void sleep() {
        System.out.println("睡觉");
    }
}
class Student extends Person {}

class Teacher extends Person {}

public class ExtendsDemo {
    public static void main(String[] args) {
        Student s = new Student();
        s.eat();
        s.sleep();
        System.out.println("-------------");
        Teacher t = new Teacher();
        t.eat();
        t.sleep();
    }
}

作为小司机可以看到使用继承前后的输出结果相同
运用了继承后,我们可以看到继承的好处也就是优点

  • 提高了代码的复用性
    • 多个类相同的成员可以放到同一个类中
  • 提高了代码的维护性
    • 如果功能的代码需要修改,修改一处即可
  • 让类与类之间产生了关系,是多态的前提

当然运用了继承后,他也是存在弊端的

  • 类的耦合性很强
    设计原则:高内聚低耦合。
    简单的理解:
    内聚就是自己完成某件事情的能力。
    耦合就是类与类之间的关系。
    我们在设计的时候原则是:自己能完成的就不麻烦别人,这样将来别人产生了修改,就对我的影响较小。
    由此可见:在开发中使用继承其实是在使用一把双刃剑。今天我们还是以继承的好处来使用,因为继承还有很多其他的特性。

我们了解了继承的概述,继续了解Java中继承的特点

  • Java只支持单继承,不支持多继承。
    • 一个类只能有一个父类,不可以有多个父类。
    • class SubDemo extends Demo{} //ok
    • class SubDemo extends Demo1,Demo2…//error
  • Java支持多层继承(继承体系)
    • class A{}
    • class B extends A{}
    • class C extends B{}

我们一起写个小Demo验证继承的特点!

//Java只支持单继承,不支持多继承。
class Father {}
class Mother {}
class Son exnteds Father {} //正确的
class Son extends Father,Mother {} // 错误的

//Java支持多层继承
class GrandFather {
    public void show() {
        System.out.println("我是爷爷");
    }
}
class Father extends GrandFather {
    public void method(){
        System.out.println("我是老子");
    }
}
class Son extends Father {}
class ExtendsDemo2 {
    public static void main(String[] args) {
        Son s = new Son();
        s.method(); //使用父亲的
        s.show(); //使用爷爷的
    }
}

那么,在Java中继承的注意事项有哪些呢?

  • 子类只能继承父类所有非私有的成员(成员方法和成员变量)
    • 其实这也体现了继承的另一个弊端:打破了封装性
  • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
  • 不要为了部分功能而去继承
  • 我们到底在什么时候使用继承呢?
    • 继承中类之间体现的是:”is a”的关系。
    • 举例:水果和苹果,苹果是一种水果。
    • 学生和人,学生是人的一种。
    • 所以我们总结采用假设法。如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
class Father {
        private int num = 10;
        public int num2 = 20;

        //私有方法,子类不能继承
        private void method() {
            System.out.println(num);
            System.out.println(num2);
        }

        public void show() {
            System.out.println(num);
            System.out.println(num2);
        }
    }
    class Son extends Father {
        public void function() {
            //num可以在Father中访问private
            //System.out.println(num); //子类不能继承父类的私有成员变量
            System.out.println(num2);
        }
    }
public class ExtendsDemo {

    public static void main(String[] args) {
        // 创建对象
                Son s = new Son();
                //s.method(); //子类不能继承父类的私有成员方法
                s.show();
                s.function();
    }
}

输出结果:
10
20
20

继承中成员变量的关系

  • A:子类中的成员变量和父类中的成员变量名称不一样,这个太简单。
  • B:子类中的成员变量和父类中的成员变量名称一样,这个怎么玩呢?
    • 结论在子类方法中访问一个变量的查找顺序:
      • a:在子类方法的局部范围找,有就使用
      • b:在子类的成员范围找,有就使用
      • c:在父类的成员范围找,有就使用
      • d:如果还找不到,就报错。
class Father {
    public int num = 10;

    public void method() {
        int num = 50;
    }
}

class Son extends Father {
    public int num2 = 20;
    public int num = 30;

    public void show() {
        int num = 40;
        System.out.println(num);
        System.out.println(num2);
        // 找不到符号,报错
        //System.out.println(num3);
    }
}
public class ExtendsDemo {

    public static void main(String[] args) {
                // 创建对象
                Son s = new Son();
                s.show();   
    }
}

输出结果:
这里写图片描述
记住上面的结论,到哪里都不会出错的
下面来学习super关键字

super关键字

  • super的用法和this很像
    • this代表本类对应的引用。
    • super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
  • 用法(this和super均可如下使用)
    • 访问成员变量
      • this.成员变量 调用本类的成员变量
      • super.成员变量 调用父类的成员变量
  • 访问构造方法
    • this(…) 调用本类的构造方法
    • super(…) 调用父类的构造方法
  • 访问成员方法
    • this.成员方法() 调用本类的成员方法
    • super.成员方法() 调用父类的成员方法
class Father {
    public int num = 10;
}

class Son extends Father {
    public int num = 20;

    public void show() {
        int num = 30;
        System.out.println(num);
        System.out.println(this.num);
        System.out.println(super.num);
    }
}

public class ExtendsDemo{
    public static void main(String[] args) {
        Son s = new Son();
        s.show();
    }
}

输出结果:
这里写图片描述

继承中构造方法的关系

  • 子类中所有的构造方法默认都会访问父类中空参数的构造方法
    • 因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。
    • 注意:子类每一个构造方法的第一条语句默认都是:super();
class Father {
    int age;

    public Father() {
        System.out.println("Father的无参构造方法");
    }

    public Father(String name) {
        System.out.println("Father的带参构造方法");
    }
}
class Son extends Father {
    public Son() {
        //super();
        System.out.println("Son的无参构造方法");
    }

    public Son(String name) {
        //super();
        System.out.println("Son的带参构造方法");
    }
}   

public class ExtendsDemo {
    public static void main(String[] args) {
        //创建对象
        Son s = new Son();
        System.out.println("------------");
        Son s2 = new Son("宝宝");
    }
}

输出结果:
这里写图片描述

如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?我注释了上面例子中父类的无参构造,然后项目报错了,那么我们怎么解决呢?

  1. 在父类中加一个无参构造方法
  2. 通过使用super关键字去显示的调用父类的带参构造方法
  3. 子类通过this去调用本类的其他构造方法
  4. (子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。)
  5. 注意事项
  6. this(…)或者super(…)必须出现在第一条语句上。
  7. 如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。

上面说了这么多,不知道你是否理解了,我们通过Demo再来学习

class Father {
    int age;

    /*public Father() {
        System.out.println("Father的无参构造方法");
    }*/

    public Father(String name) {
        System.out.println("Father的带参构造方法");
    }
}
class Son extends Father {
    public Son() {
        super("111");
        System.out.println("Son的无参构造方法");
//      super("111");
    }

    public Son(String name) {
//      super("222");
        this();
        System.out.println("Son的带参构造方法");
    }
}
public class ExtendsDemo {

    public static void main(String[] args) {
                //创建对象
                Son s = new Son();
                System.out.println("------------");
                Son s2 = new Son("宝宝");
    }
}

输出结果:不知道你通过上面的概念是否能观察出结果呢,不能的话就要去多想多练多理解
这里写图片描述

继承中成员方法的关系:

  • A:子类中的方法和父类中的方法声明不一样,这个太简单。
  • B:子类中的方法和父类中的方法声明一样,这个该怎么玩呢?
    • 通过子类对象调用方法:
      • a:先找子类中,看有没有这个方法,有就使用,没有就在父类中找
      • b:再看父类中,有没有这个方法,有就使用
      • c:如果没有就报错。

方法重写、方法重载

  • 方法重写概述
    • 子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。
  • 方法重载概述
    • 本类中出现的方法名一样,参数列表不同的方法。与返回值无关。
  • 使用特点:
    • 如果方法名不同,就调用对应的方法
    • 如果方法名相同,最终使用的是子类自己的
  • 方法重写的应用:
    • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
class Phone {
    public void call(String name) {
        System.out.println("给"+name+"打电话");
    }
}
class NewPhone extends Phone {
    public void call(String name) {
        super.call(name);
        System.out.println("打完电话了,我要听首歌");
    }
}
public class ExtendsDemo {

    public static void main(String[] args) {
        NewPhone np = new NewPhone();
        np.call("老板");
    }
}

输出结果:
这里写图片描述
上面的Demo中,手机打电话功能,是手机本身就具备的最基本的功能。所以,新手机是不用在提供这个功能的。由于它继承了手机类,所以,我们就直接使用父类的功能即可。通过super关键字调用

  • 方法重写的注意事项
    • A:父类中私有方法不能被重写(因为父类私有方法子类根本就无法继承)
    • B:子类重写父类方法时(访问权限不能更低,最好就一致)
    • C:父类静态方法,子类也必须通过静态方法进行重写
    • 子类重写父类方法的时候,最好声明一模一样。

我们一起来做两个经典例题

  • 方法重写(Override)和方法重载(Overload)的区别?方法重载能改变返回值类型吗?

    方法重写:在子类中,出现和父类中一模一样的方法声明的现象。
    方法重载:同一个类中,出现的方法名相同,参数列表不同的现象。

    方法重载能改变返回值类型,因为它和返回值类型无关。

  • this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。

    this:代表当前类的对象引用
    super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)
    场景:
    成员变量:this.成员变量——super.成员变量
    构造方法:this(…)——super(…)
    成员方法:this.成员方法——super.成员方法


好了,今天我们学了这么多,要好好消化一下,做到学以致用。最后送大家一句话。
不管有多苦,千万要记住:苦难是我们人生路上不可缺少的经历,只有活着,才有幸福的可能!

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java基础_super()用法和继承的关系

下面的文章是转载自http://greateryang.blog.163.com/blog/static/81953375201232661845898/ 看完这篇文章,你可以理顺super()的...
  • s389747131
  • s389747131
  • 2014年12月19日 13:30
  • 807

Java 继承(extends)详解

一、继承问题的引出 继承性是面向对象的第二大主要特征。 下面首先编写两个程序:Person类、Student类。 Person类: class Person { priv...
  • wei_zhi
  • wei_zhi
  • 2016年10月11日 10:55
  • 2912

java中this & super关键字

一、this关键字   1.this是指当前对象自己 当在一个类中要明确指出使用对象自己的的变量或函数时就应该加上this引用。如下面这个例子中:   运行结果:   s=HelloWorl...
  • yu422560654
  • yu422560654
  • 2012年02月27日 19:30
  • 3399

java继承中super关键词

super关键字的用法: 1:若果子类父类存在同名的成员变量时,可以使用super关键字来引用父类的成员变量。而在子类中默认是访问子类的成员变量。 2:在创建子类对象时,会先默认调用父类中的无参构...
  • A541006070
  • A541006070
  • 2016年11月16日 18:03
  • 268

Java(方法重写与变量覆盖)(super,this的使用)

在类的继承过程中,如果子类中新增的变量和方法与父类中原有的变量和方法同名,则会覆盖从父类继承来的同名变量和方法。覆盖又分为变量覆盖和方法覆盖,变量覆盖是指父类和子类中的变量名相同,数据类型也相同。方法...
  • JACK_JYH
  • JACK_JYH
  • 2016年08月29日 21:55
  • 1131

Java继承,子类默认在构造函数中用super()调用父类构造函数

1.子类继承父类的方法属性,并重写父类的方法,子类修饰符不能比父类方法的修饰符的范围狭窄。 Protect 与 默认 区别: protected :成员 本类和子类可以访问。【其他类不可以使用(即使...
  • yingtian648
  • yingtian648
  • 2016年06月02日 08:54
  • 3688

Java 中的继承的简单例子(super关键字)

class Cleanser{ private String s="Cleanser"; public void append(String a){s+=a;} public void dilu...
  • u014112584
  • u014112584
  • 2015年01月15日 14:13
  • 1242

java学习笔记-继承中super关键字

背景: 在java继承的概念中我们得知,被声明为私有的类成员对所属的类来说仍然是私有的。类之外的任何代码都不能访问,包括子类。 super关键字的两种用法: 1.用于调用超类的构造函数; 2.用于访...
  • li898445911a
  • li898445911a
  • 2013年09月04日 15:45
  • 1926

Java继承、super、继承访问权限

继承的概念 继承体现为两个类之间的一般与特殊的关系。如果A类是一种特殊的B类,则A继承B。我们将B称为父类,A称为子类。继承使用extends关键字。子类继承了父类,子类就称为一种特殊的父类,子类便...
  • LVAmber
  • LVAmber
  • 2017年04月17日 14:59
  • 529

java构造函数是否可继承,以及子类构造函数可否不使用super调用超类构造函数

本文作者水平有限,可能有很多错误,望指正。 问题一:java的构造函数能否被继承? 笔者初学java看的一本书说:“java的子类自然的继承其超类的“非private成员”。 通常jav...
  • iamluole
  • iamluole
  • 2012年09月13日 02:44
  • 7156
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA基础再回首(六)——父与子的继承、super关键字、方法重写、方法重载
举报原因:
原因补充:

(最多只允许输入30个字)