首页 > 技术文章 > java继承

lzylcf 2018-08-11 15:12 原文

继承:

  每一个扩展类继承基类都可以看成人类衍生出不同的人。

  人的本能,都会通过语言交流、吃饭等。但是每个人说话的方式和吃饭方式会因为环境的不同而不同。

  比如一个人,他说中文,他吃饭用的是筷子。另一个人,他说英语,他吃饭用刀叉。

  都属于人类,拥有同样的行为,但是这些行为的实现方式都是不同的。

  

  通过代码实现继承

/**
 * 父类
 */
class People{
    public void say(){
        System.out.println("say");
    }
    public void eat(){
        System.out.println("eat");
    }
}

/**
 * 子类
 */
class YellowRace extends People{
    
}

public class initBaseClass {
    public static void main(String[] args) {
        //继承的子类可以拥有父类的方法
        YellowRace yellowRace = new YellowRace();
        yellowRace.say();
        yellowRace.eat();
    }
}
/**
 * output: 
 *  say
 *  eat
 */

  继承父类的子类可以拥有父类的方法,这样黄种人(YellowRace)就有了人(People)的本能,但是现在黄种人拥有了自己的语言和吃饭的方式,原先人类的说话方式就会被丢弃,就在YellowRace这个类中重写人这个类中的方法,@Override这个注解是表明重写了下面的方法,当然也可以不写,将子类修改成下面的代码

/**
 * 子类
 */
class YellowRace extends People{
  @Override
public void say(){ System.out.println("i speak chinese"); }
  @Override
public void eat(){ System.out.println("i eat with chopsticks"); } }
/**
 * output: 
 *  i speak chinese
 *  i eat with chopsticks
 */

会了自己的说话方式,但是又不想忘记以前的交流方式,则通过super这个关键字去调用父类的方法,为什么不能直接调用方法,而要通过super去调用呢,因为直接调用方法会产生递归,变成死循环,所以java提供了super这个关键字去调用父类。修改子类方法

/**
 * 子类
 */
class YellowRace extends People{
    public void say(){
        super.say();
        System.out.println("i speak chinese");
    }
    public void eat(){
        super.eat();
        System.out.println("i eat with chopsticks");
    }
}
/**
 * output: 
 *  say
 *  i speak chinese
 *  eat
 *  i eat with chopsticks
 */

 

现在的黄种人有了自己的说话方式和吃饭方式,突然发现这两个人的本能不够生存,现在需要学会走路去找吃的,即扩展继承的类


/**
* 父类
*/
  class People{
    public void say(){
      System.out.println("say");
    }
    public void eat(){
      System.out.println("eat");
    }

  }

/**
 * 子类
 */
class YellowRace extends People{
    public void say(){
        System.out.println("i speak chinese");
    }
    public void eat(){
        System.out.println("i eat with chopsticks");
    }
    public void walk(){
        System.out.println("i walk to find food");
    }
}

public class initBaseClass {
    public static void main(String[] args) {
        //继承的子类可以拥有父类的方法
        YellowRace yellowRace = new YellowRace();
        yellowRace.say();
        yellowRace.eat();
        yellowRace.walk();
    }
}
/**
 * output: 
 *  i speak chinese
 *  i eat with chopsticks
 *  i walk to find food
 */

要注意的几个点:

  1、子类在继承父类后,初始化时会先调用父类默认的无参构造方法,用来初始化方法和属性。

  当父类定义一个有参构造方法,而子类继承后在构造方法中没有调用父类的有参构造方法,则会报错,因为子类默认调用父类的无参构造方法,要通过super去调用父类已定义的构造方法。

/**
 * 父类
 */
class People{
    public People(int i){
        System.out.println("init People");
    }
}

/**
 * 子类
 */
class YellowRace extends People{
    public YellowRace(int i) {
        super(i);
        System.out.println("init yellowRace");
    }
}

public class initBaseClass {
    public static void main(String[] args) {
        YellowRace yellowRace = new YellowRace(1);
    }
}
/**
 * output: 
 *    init People
 *    init yellowRace
 */

  2、父类中的私有方法和私有属性,无法被子类继承,protected可以被继承并调用

/**
 * 父类
 */
class People{
    public People(int i){
        System.out.println("init People");
    }
    private void say(){
        System.out.println("i speak");
    }
    protected void walk(){
        System.out.println("i walk");
    }

}

/**
 * 子类
 */
class YellowRace extends People{
    public YellowRace(int i) {
        super(i);
        System.out.println("init yellowRace");
    }
}

public class initBaseClass {
    public static void main(String[] args) {
        YellowRace yellowRace = new YellowRace(1);
        yellowRace.say();// 错误信息: The method say() from the type People is not visible 这个方法是不可见的,无法被子类调用
        yellowRace.walk();
    }
}
/**
 * output: 
 *    init People
 *    init yellowRace
 *    i walk
 */

   3、当父类的第一个方法调用第二个方法,而子类覆写了第二个方法,创建子类后,则父类的第一个方法则会去调用被子类覆写的第二个方法。因为运行时,程序会先查找子类是否存在该方法,不存在则从父类中继承,子类拥有第二个方法,则会被调用。

推荐阅读