面向对象之继承

主要通过extends来实现,子类对父类的继承,实际上是子类对父类的扩展,子类是一种特殊的父类。

子类继承父类:可以调用父类非私有的的成员(成员变量、成员方法)

java子类继承父类构造方法 java子类继承父类简单实例_开发语言


高内聚低耦合是程序设计的追求。

耦合:两个(或更多)模块相互依赖对方(齿轮之间耦合转动,只要一个出错,另一个就无法正常工作)

内聚:模块内部结构紧密,独立性强。

案例1:动物类继承

main方法

package itcast.demo1;

public class TestAnimal {
    public static void main(String[] args) {
        Dog h = new Dog();
        h.eat("小黑");
        h.watch();

        Pig g = new Pig();
        g.snore();
    }
}

Animal父类

ackage itcast.demo1;

public class Animal {
    //  成员变量
    private String name;
    private int age;
    private String sex;
    //  构造方法
    public Animal() {
    }

    public Animal(String name, int age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    //  成员方法
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void eat(String name){
        this.name = name;
        System.out.println(name +"干饭");
    }
}

动物子类

package itcast.demo1;

public class Dog extends Animal{
    //成员方法
    public void watch(){
        System.out.println("发动看家技能....");
    }
}
package itcast.demo1;

public class Pig extends Animal{
    public void snore(){
        System.out.println("睡大觉");
    }
}

当子类存在自己特殊行为或是特点时,写到子类当中即可

优点:功能复用,便于扩展新功能,结构清晰,简化认识,易于维护
缺点:打破封装性,子类的实现细节暴露在父类当中,具有高耦合性,类与类之间相互依赖性较高

子父类中定义了同名的成员变量,如何使用?用到super方法

package itcast.demo2;

public class Test {
    public static void main(String[] args) {
        c a = new c();
        a.price();
    }
}
package itcast.demo2;

public class p {
    int price = 20;

    public p() {
    }

    public p(int price) {
        this.price = price;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}
package itcast.demo2;

public class c extends p{
    int price = 10;
    public void price(){
        int price = 5;
        System.out.println(price);
        System.out.println(this.price);
        System.out.println(super.price);//打印父类的成员变量
        /*但是父类中如果有private修饰的成员变量,这里就不能打印*/
         Person c = new Person();
        c.show4();
    }
}

继承关系中成员变量使用

  1. 查找变量的原则:就近原则
  2. 查找变量的顺序:局部变量→成员变量→父类→更高的父类…Object
  3. 访问父类变量的方式:super.xxx
  4. super:当前对象父类的引用
  5. 对象初始化顺序:先初始化父类内容,再初始化子类内容

继承关系中成员方法使用

  1. 查找方法的原则:就近原则
  2. 查找方法的顺序:本类→父类→更高的父类…Object
  3. 访问父类变量的方式:super.父类方法名();
  4. 定义重名方法的前提:父类功能不能满足现实需求,扩展父类功能;父类功能已过时,重新实现父类功能。

子父类的构造方法——无参构造、带参构造

package itcast.demo4;
/*测试类
子类所有的构造方法第一行都会有一个默认的super()用来访问父类的无参构造方法,写不写都可以
若父类是带参构造,通过super(参数)访问父类的带参构造
* */
public class Test {
    public static void main(String[] args) {
        Worker a =new Worker();
    }
}

无参构造

package itcast.demo4;

// 父类
public class Person {
    public Person(){
        System.out.println("Person类 空参构造");
    }
}
package itcast.demo4;

//子类
public class Worker extends Person{
    public Worker(){
     super();//这一行,写不写都存在
        System.out.println("Worker类 空参构造");
    }
}

直接运行的结果

Person类 空参构造
Worker类 空参构造

带参构造

package itcast.demo4;

// 父类
public class Person {
    public Person(String name){
        System.out.println("Person类 带参构造   "+name);
    }
}
package itcast.demo4;

//子类
public class Worker extends Person{
    public Worker(){
        super("大橘");
        System.out.println("Worker类 空参构造");
    }
}

运行结果

Person类 带参构造   大橘
Worker类 空参构造

方法重写
子类当中出现与父类方法定义相同的方法现象(方法名、参数列表、返回值类型都相同)
父类中私有的方法无法重写;子类方法的访问权限不能小于父类方法,且不能抛出比父类方法更大的异常。
常用于重名父类方法的情形。
四大修饰符权限的修饰范围从小到大分别是:private、默认(啥也不写)、protected、public
方法重载:同一个类中方法名相同,其他无关紧要

package itcast.demo4;

import itcast.demo2.Woker0;

/*测试类
              本类       同包下的子类   不同包下的子类   不同包下的无关类
 private        Y
 默认           Y            Y
 protected      Y            Y              Y
 public         Y            Y              Y               Y
* */
public class Test {
    public static void main(String[] args) {
        Worker a =new Worker();
        a.show2();a.show3();a.show4();

        Woker0 b = new Woker0();
        b.show3();b.show4();
        // 不同包下的无关类写在demo2的继承p的c子类中调用Person类的show4

    }
}
package itcast.demo4;

// 父类,这里也是可以写main方法的
public class Person {
    private void show1(){
        System.out.println("show1 private");
    }

    void show2(){
        System.out.println("show2 default");
    }

    protected void show3(){
        System.out.println("show3 protected");
    }

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

    public static void main(String[] args) {
        Person c = new Person();
        c.show1();c.show2();c.show3();c.show4();
    }
package itcast.demo4;

//子类
public class Worker extends Person{

    }

总结
private:给自己用
default:给同一个包用
protected:给子类用(不管是不是同一个包)
public:给大家用

继承特点

  1. 单类继承(但是可以多层继承 父类(子类(子类(…))));
  2. 多接口继承 (接口A extends 接口B,接口C,接口D,…)
  3. 父类私有无法继承
  4. 构造方法不能被继承,只能被调用
  5. 子类符合"is a"父类的情况才能使用继承,其他情况可以但不建议。“Apple is a fruit.”