02_面向对象高级_继承

继承

1. 认识继承

概念 => Java 中提供了一个关键字 extends,用这个关键字,可以让一个类和另一个类建起父子关系

特点 => 子类能继承父类的非私有成员(成员变量、成员方法)

对象 => 子类的对象是由子类、父类共同完成的

好处 => 减少了重复代码的编写,提高了代码的复用性。

public class HelloWorld {
    public static void main(String[] args) {
        B obj = new B();
        System.out.println(obj.i);  // 正确
    //  System.out.println(obj.j);  // 报错
        System.out.println(obj.x);  // 正确
    //  System.out.println(obj.y);  // 报错
    }
}

class A {
    public int i;
    private int j;
}

class B extends A {
    public int x;
    private int y;
}
2. 继承的注意事项

2.1 权限修饰符

修饰符 在本类中 同一个包下的其他类里 任意包下的子类里 任意包下的任意类里
private
缺省(即:不写)
protected
public

2.2 单继承

Java 是单继承的,Java 中的类不支持多继承,但是支持多层继承。

Object 类是 Java 所有类的祖宗类。我们写的任何一个类,其实都是 Object 的子类或子孙类。

2.3 方法重写

2.3.1 概念:

  • 当我们觉得父类中的某个方法不好用时,或者无法满足自己的需求时,我们可以在子类中重写一个方法名称、参数列表都和父类一样的方法,用它来覆盖父类的这个方法,这个就是方法重写。
  • 但是请注意,重写后,方法的访问,Java 会遵循就近原则。

2.3.2 注意事项:

  • 当我们重写时,在子类重写方法的头顶上加上@Override,就能使用Override注解,它可以指定 Java 编译器,检查我们方法重写的格式是否正确,代码可读性也会更好。
  • 子类重写父类的方法时,访问权限必须大于或等于父类该方法的权限(public > protected > 缺省)
  • 重写的方法返回值类型,必须与被重写方法的返回值一样,或者范围更小。
  • 私有方法、静态方法不能被重写,如果重写会报错。
public class HelloWorld {
    public static void main(String[] args) {
        B obj = new B();
        obj.printStr();  // Hello World
    }
}

class A {
    public void printStr() {
        System.out.println("Good");
    }
}

class B extends A {
    @Override  // 安全、可读性好
    public void printStr() {
        System.out.println("Hello World");
    }
}

2.4 访问其他成员:

  • 在子类方法中访问其他成员(成员变量、成员方法),也是依照就近原则。

  • 如果在子类中重写了父类的方法(或变量),但是又想访问原来父类的方法(或变量),可以使用 super 关键字,例如:super.方法名( ) (或 super.变量名)。同样的道理,也可以恰当使用 this 关键字进行相关操作。

2.5 子类构造器的super(…)与this(…):

  • 子类的含参或无参构造器,都会先调用父类的无参构造器,再执行自己的构造器
  • 原因是因为,子类构造器的第一行默认隐藏了一行代码,就是 super( ),当它被执行时,就会去找父类的无参构造器并运行
  • 而如果在父类中,构造器只有含参构造器,例如 Father( String name,int age ) {…} ,子类需要使用父类的构造器,但是子类构造器中默认只有 super( ) ,执行将会报错;这时我们需要自己写 super( ),例如这里需要写成 super( name , age )
  • 如果说 super(…) 是调用父类的构造器,那么,同样的道理,this(…) 是调用自己同级别的构造器,比如在子类 Son( String name ) 构造器里面写上 this( String name,int age= 18 ),则它会调用自己同级别的另一个构造器 Son( String name,int age ),这样的话,如果 Son( String name,int age ) 构造器里面有xxx代码的话,Son( String name ) 构造器就不需要重写一遍了!
class A {
    public A() {
        System.out.println("父类的无参构造器");
    }
}

class B extends A {
    public B() {
    //  super()     // 子类构造器(含参或无参),都默认隐藏了这行代码
    //  |           //  而这行代码作用是运行父类的构造器
    //  |           //  如果父类构造器需要参数,则我们需要自己写一个super( 括号里面填写父类需要的参数 )
    //  |
        System.out.println("子类的无参构造器");
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        B obj = new B();
        // 运行结果:
        
        //  父类的无参构造器
        //  子类的无参构造器
    }
}

你可能感兴趣的:(Java进阶,java)