继承

作者: 醒醒Coco | 来源:发表于2017-06-21 17:39 被阅读0次

概述
多个类中存在相同的属性和行为时,可以把这些内容抽取到单独的一个类中。通过extends关键字可以实现继承.单独的这个类叫做父类,基类或者超类。多个类可以称为子类或者派生类。

作用

  • 提高了代码复用性
  • 提高了代码的维护性
  • 让类和类之间产生了关系,是多态的前提(其实也是继承的弊端,类的耦合性增加了)
    开发的原则:低耦合,高内聚
    耦合:类与类的关系
    内聚:就是自己完成某件事情的能力

Java中继承的特点

  • Java中只支持单继承,不支持多继承
  • Java支持多层继承(继承体系)

继承的注意事项

  • 子类只能继承父类所有非私有的成员方法和成员变量
  • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法
  • 不要为了部分功能而去继承
    什么时候考虑使用继承?继承其实是一种关系"is a"

继承中成员变量的关系

  • 子类中的成员变量和父类中的成员变量不一样
  • 子类中的成员变量和父类中的成员变量一样。就近原则

super 和 this 的区别
this 代表本类对象的引用。super 代表父类存储空间的标识,可以理解为父类的引用。

  • 成员变量的调用
  this.成员变量  调用本类的成员变量
  super.成员变量  调用父类的成员变量
  • 构造方法的调用
  this(...)    调用本类的构造方法
  super(...)   调用父类的构造方法
  • 成员方法的调用
  this.成员方法    调用本类得成员方法
  super.成员方法   调用父类得成员方法

ExtendsDemo

package coco.perm;
/**
 * Created by xingxingduan on 2016/5/2.
 * 继承概述:
 * 把多个类中相同的内容给提取出来定义到一个类中。
 * 如何实现继承呢?
 * Java提供了关键字:extends
 * 格式:
 *class 子类名 extends 父类名 {}
 *
 */

class Person{
    public void eat(){
        System.out.println("吃饭");
    }

    public void sleep() {
        System.out.println("睡觉");
    }
}

class Student1 extends Person{}
//通过继承关系,省去大量的代码。子类可以继承父类未被private修饰的成员变量和成员方法。

class Teacher extends Person{}

public class ExtendsDemo {
    public static void main(String[] args) {
        Student1 s = new Student1();
        s.eat();
        s.sleep();
        System.out.println("_________________________");

        Teacher t = new Teacher();
        t.eat();
        t.sleep();
    }
}

ExtendsDemo2

/**
 * Created by xingxingduan on 2016/5/2.
 * Java中继承的特点:
 * 1、Java中只支持单继承,不支持多继承
 *      有些语言支持多继承:格式:extends 类1,类2,...
 * 2、Java支持多层继承(继承体系)
 */

class GrandFather{
    public void show(){
        System.out.println("我是爷爷");
    }
}

class Father extends GrandFather{
    public void method(){
        System.out.println("我是老子");
    }
}

class Son extends Father{}

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

ExtendsDemo3

package coco.perm;

/**
 * Created by xingxingduan on 2016/5/10.
 * 继承的注意事项:
 *      A:子类只能继承父类所有非私有(未被private关键字修饰的)的成员(成员方法和成员变量)
 *      B:子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
 *      C:不要为了部分功能而去继承  
 */
class Father{
    private int num = 10;
    public int num1 = 20;

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

    public void show(){
        System.out.println(num);
        System.out.println(num1);
    }
}

class Son extends Father{
    public void function(){
        //子类不能继承父类的私有成员变量
        System.out.println(num1);
    }
}

public class ExtendDemo3 {
    public static void main(String[] args) {
        Son s = new Son();
        //之类不能继承父类的私有成员方法
        s.show();
        
    }
}

继承中构造方法的关系

  • 子类中所有的构造方法默认都会访问父类中无参的构造方法
  • 原因:因为子类会继承父类的数据,甚至还会使用父类的数据。所以,子类初始化前,一定要先完成父类的初始化
  • 子类中每一个构造方法的第一个语句默认是 super()
class Father1 {
    public Father1() {
        System.out.println("这是Father的无参构造方法");
    }
    public Father1(String name) {
        System.out.println("这是Father的带参数构造方法");
    }
}
class Son1 extends Father1 {
    public Son1() {
        //子类的构造方法,默认第一天语句是super()
        //super();    //可写可以不写
        System.out.println("这是Son的无参构造方法");
    }
    public Son1(String name) {
        //super();
        System.out.println("这是Son的带参数构造方法");
    }
}
public class ExtendsDemo {

    public static void main(String[] args) {
        Son1 s = new Son1();
        System.out.println("-----------------");

        Son1 s1 = new Son1("xingxing");
    }
}

如果父类中没有无参构造方法,怎么办?
错误示例

class Father2{
    public Father2(String name){
        System.out.println("这是Father2的带参构造方法");
    }
}
class Son2 extends Father2{
    public Son2(){
        System.out.println("这是Son2的无参构造方法");
    }
    public Son2(String name){
        System.out.println("这是Son2的带参构造方法");
    }
}
public class ExtendDemo2 {
    public static void main(String[] args) {
        Son2 s = new Son2();
    }
}
程序报错:
Error:(11, 18) java: 无法将类 Father2中的构造器 Father2应用到给定类型;
  需要: java.lang.String
  找到: 没有参数
  原因: 实际参数列表和形式参数列表长度不同

解决方法

  • 在父类中加一个无参构造方法
  • 通过使用super关键字去显示的调用父类中的带参构造方法
  • 通过this去调用本类中的其他构造方法(子类中一定要有一个去访问了父类的构造方法,否则,父类的数据没有初始化)
class Father2{
    public Father2(String name){
        System.out.println("这是Father2的带参构造方法");
    }
}
class Son2 extends Father2{
    public Son2(){
        super("随便填");
        System.out.println("这是Son2的无参构造方法");
    }
    public Son2(String name){
        //super("随便填");
        this();
        System.out.println("这是Son2的带参构造方法");
    }
}
public class ExtendDemo2 {
    public static void main(String[] args) {
        Son2 s = new Son2();
        System.out.println("-----分割线--------");
        Son2 s2 = new Son2("coco");
    }
}
运行结果:
这是Father2的带参构造方法
这是Son2的无参构造方法
-----分割线--------
这是Father2的带参构造方法
这是Son2的无参构造方法
这是Son2的带参构造方法

继承中成员方法关系

  • 子类中的方法和父类中的方法声明不一样
class Father1{
    public void show(){
        System.out.println("show Father");
    }
}
class Son1 extends Father1{
    public void method(){
        System.out.println("method Son");
    }
}
public class ExtendsDemo1 {
    public static void main(String[] args) {
        Son1 s = new Son1();
        s.show();
        s.method();
    }
}
运行结果:
show Father
method Son
  • 子类中的方法和父类中的方法声明一样,先找子类本身,再找父类。
class Father1{
    public void show(){
        System.out.println("show Father");
    }
}
class Son1 extends Father1{
    public void show(){
        System.out.println("show Son");
    }
}
public class ExtendsDemo1 {
    public static void main(String[] args) {
        Son1 s = new Son1();
        s.show();
    }
}
输出结果:
show Son

方法重写

子类中出现了和父类中方法声明一摸一样的方法。
当子类中,需要使用父类的功能,而功能主题有自己持有内容时,可以重写父类中的方法。这样,既沿袭了父类的功能,又定义了子类持有的内容。可以通过super关键字调用。

class Phone{
     public void call(String name){
        System.out.println("给"+name+"打电话");
    }
}
class NewPhone extends Phone{
    public void call(String name){
        super.call(name);    //通过super关键字调用
        System.out.println("可以听天气预报了");
    }
}
public class ExtendsDemo3 {
    public static void main(String[] args) {
        NewPhone np = new NewPhone();
        np.call("xingxing");
    }
}

注意

  • 父类中的私有方法,不能被重写。因为父类的私有方法,子类根本无法继承。
  • 子类重写方法时,访问权限不能更低。只能大于等于父类的权限,最好一致。

问题

  1. override 和overload 的区别,能改变返回值类型吗?
    方法重写(override):在子类中出现和父类中一模一样的方法声明时。
    方法重载(overload):同一个类中,出现方法名相同,参数列表不同。方法重载可以改变返回值的类型,因为它与返回值类型无关。方法重写不可以。

  2. this 和 super的区别?
    this代表当前类的引用
    super代表父类存储空间的标识(可以理解为父类的引用,通过这个访问父类的成员)

练习案例

/**
 * Created by v_xxingduan on 2015/6/22.
 * 学生和老师的案例
 */

class Person{
    //姓名
    private String name;
    //年龄
    private int age;

    public Person(){}

    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}


class Students extends Person{
    public Students(){}

    public Students(String name,int age){
        super(name,age);   //显示调用父类的带参构造
    }
}

class Teacher extends Person{
    public Teacher(){}

    public Teacher(String name,int age){
        super(name,age);
    }
}
public class ExtendsDemo4 {
    public static void main(String[] args) {
        Students s1 = new  Students();
        s1.setName("xingxing");
        s1.setAge(20);
        System.out.println(s1.getName()+"----"+s1.getAge());

        Teacher t1 = new Teacher("coco",21);
        System.out.println(t1.getName()+"----"+t1.getAge());
    }
}
/**
 * Created by xingxingduan on 2015/6/22.
 * 猫和狗的案例
 */

class Animal{
    //姓名
    private String name;
    //年龄
    private int age;
    //颜色
    private String color;

    //构造方法
    public Animal(){}

    public Animal(String name,int age,String color){
        this.name = name;
        this.age = age;
        this.color = color;
    }

    //成员方法
    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getColor() {
        return color;
    }
}

class Cat extends Animal{
    public Cat(){}

    public Cat(String name,int age,String color){
        super(name,age,color);
    }

    public void playGame(){
        System.out.println("Cat PlayGame");
    }
}


class Dog extends Animal{
    String hobby;
    public Dog(){}

    public Dog(String name,int age,String color,String hobby){
        super(name,age,color);
        this.hobby = hobby;
    }

    public void lookDog(){
        System.out.println("LookDog");
    }
}

public class ExtendsDemo5 {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.setName("cat");
        c.setAge(2);
        c.setColor("balck");
        System.out.println("name:"+c.getName()+"\tage:"+c.getAge()+"\tcolor:"+c.getColor());
        c.playGame();

        Dog d = new Dog("coco",3,"yellow","eat");
        System.out.println("name:"+d.getName()+"\tage:"+d.getAge()+"\tcolor"+d.getColor()+"\thobby:"+d.hobby);
        d.lookDog();
    }
}

相关文章

  • 继承 继承

    属性拷贝 继承不单单能通过原型链实现,也能通过其他方式实现,属性拷贝就是其中一种方法。 通过属性拷贝也能实现继承子...

  • 继承(单继承,多继承)

    将共性的内容放在父类中,子类只需要关注自己特有的内容 python中所有的内容都是对象,所有的对象都直接或间接继承...

  • js继承方式

    类式继承 构造函数继承 组合继承 类式继承 + 构造函数继承 原型式继承 寄生式继承 寄生组合式继承 寄生式继承 ...

  • Python-学习之路-08 OOP -02

    单继承和多继承 单继承:每个类只能继承一个类 多继承:每个类可以继承多个类 单继承的多继承的优缺点 菱形继承/钻石...

  • 原型相关(二)

    1.继承 继承方式:接口继承(只继承方法签名)实现继承(继承实际的方法)ECMAScript只支持实现继承,并且主...

  • 继承

    继承的引入和概述 继承案例和继承的好处 继承的弊端 Java中继承的特点 继承的注意实现和什么时候使用继承 继承中...

  • Java面向对象三大特性之继承

    继承 一、继承的特点 Java只支持单继承单继承 多继承 单继承、多继承优缺点①单继承优点:提高了代码的复用性,让...

  • 7、面向对象的程序设计3(《JS高级》笔记)

    三、继承 许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际方法。由...

  • 【重学前端】JavaScript中的继承

    JavaScript中继承主要分为六种:类式继承(原型链继承)、构造函数继承、组合继承、原型式继承、寄生式继承、寄...

  • js之继承

    文章主讲 JS 继承,包括原型链继承、构造函数继承、组合继承、寄生组合继承、原型式继承、 ES6 继承,以及 多继...

网友评论

      本文标题:继承

      本文链接:https://www.haomeiwen.com/subject/ugqzqxtx.html