Java开发工具

Java基础---继承

2019-08-10  本文已影响0人  iwen大大怪

继承的概念

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

继承的格式

class 父类 {
}
 
class 子类 extends 父类 {
}

为什么要用继承

在不同的类中也可能会有共同的特征和动作,可以把这些共同的特征和动作放在一个类中,让其它类共享。

因此可以定义一个通用类,然后将其扩展为其它多个特定类,这些特定类继承通用类中的特征和动作。

继承是 Java 中实现软件重用的重要手段,避免重复,易于维护,易于理解。

继承的特征

1.子类拥有父类非private的属性,方法。
2.子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
3.子类可以用自己的方式实现父类的方法。
4.Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类,这是java继承区别于C++继承的一个特性。
5.提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)。

继承类型

java继承.png

继承关键字

继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

extends关键字

public class Animal { 
    private String name;   
    private int id; 
    public Animal(String myName, String myid) { 
        //初始化属性值
    } 
    public void eat() {  //吃东西方法的具体实现  } 
    public void sleep() { //睡觉方法的具体实现  } 
} 
 
public class Penguin  extends  Animal{ 
}

implements关键字

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

public interface A {
    public void eat();
    public void sleep();
}
 
public interface B {
    public void show();
}
 
public class C implements A,B {
}

super

1.super 是 Java提供的一个关键字
2.super用于限定该对象调用它从父类继承得到的实例变量或方法。
3.super和this相同,都不能出现在静态方法中,因为静态方法属于类的,调用静态方法的可能是个类,而不是对象,而super和this都是限定对象调用。
4.super同样也可以在子类中调用父类中被子类隐藏和覆盖的同名实例变量和同名方法。
5.在构造器中使用super,则super会用于限定于该构造器初始化的是该对象从父类继承得到的实例变量,而不是该类自己定义的实例变量。意思就是调用父类的构造器。
super限定:super紧跟一个点

super.name; super.walk();

super调用:super紧跟圆括号

super(参数)

继承注意点

1.子类只能继承父类的所有非私有的成员变量和方法。可以继承public protected 修饰的成员,不可以继承private修饰的。
2.但是可以通过父类中提供的public 的setter和getter方法进行间接的访问和操作private 的属性
3.对于子类可以继承父类中的成员变量和成员方法,如果子类中出现了和父类同名的成员变量和成员方法时,父类的成员变量会被隐藏,父类的成员方法会被覆盖。需要使用父类的成员变量和方法时,就需要使用super关键字来进行引用。
4.当创建一个子类对象时,不仅会为该类的实例变量分配内存,也会为它从父类继承得到的所有实例变量分配内存,即使子类定义了与父类中同名的实例变量。 即依然会为父类中定义的、被隐藏的变量分配内存。
5.子类不能继承获得父类的构造方法,但是可以通过super关键字来访问父类构造方法。
6.如果父类有无参构造时,所有构造方法(包含任意有参构造)自动默认都会访问父类中的空参构造方法。(自带super();)
因为:(1)因为继承的目的是子类获取和使用父类的属性和行为,所以子类初始化
之前,一定要先完成父类数据的初始化。
(2)在Java中,每个类都会默认继承Object超类,所以每一个构造方法的第
一条默认语句都是super()
7.如果父类没有无参构造,反而有其他的有参构造方法时,子类继承父类后,子类必须显式的创建构造器,不论子类的构造器是否和父类构造器中参数类型是否一致,都必须在子类的构造器中显式的通过super关键字调用和父类构造器相应参数的构造方法。否则编译都通不过。代码示例如下:

class Person {
 public Person(int age){
     System.out.println(age);
 }

}
class Student extends Person{
 public Student(int age) {
     super(age);
 }
  public Student(){
     super(10); //必须调用父类的有参构造
     System.out.println("子类可以创建其他类型构造器,但是必须显式的用super调用父类构造器")
 }
}

继承的几个问题

1.构造方法会不会被继承
构造方法是不会被子类继承的,但子类的对象在初始化时会默认调用父类的无参构造器,当父类显示写了有参构造器,且没有无参构造器。子类继承父类的时候必须显示的调用父类的有参构造器。调用的方式可以使用super(a,b)来调用;
2.static修饰符的继承
子类是不会继承父类被static修饰的方法和变量,但是可以调用;如图所示,this.a()就会报错,普通方法的继承this.method_a()就不会报错;

class A{
    public static void a(){
        System.out.println("我是静态方法");
    }
    public void method_a(){
        this.a();
    }
}
class B extends A{
    public void b(){
        this.a;
    }
    public void meteod_b(){
        this.method_a();
    }
}

继承带来的问题

   继承严重破坏了父类的封装性,每个类都应该它内部信息和实现细节,而只暴露必要的方法给其它类使用。但在继承关系中,子类可以直接访问父类的成员变量(内部信息)和方法, 从而造成子类和父类的严重耦合。
   父类的实现细节对其子类不再透明,从而导致子类可以恶意篡改父类的方法

子类继承的改进

1.为了保证父类有良好的封装性,不会被子类随意改变,设计父类通常应该遵循如下规则:
2.尽量隐藏父类的内部数据。
3.尽量把父类的所有成员变量都设置成private访问类型,不要让子类直接访问父类的成员变量。
4.不要让子类随意访问、修改父类的方法。
5.父类中那些仅为辅助其他的工具方法,应该使用private修饰,让子类无法访问方法;
6.如果父类中的方法需要被外部类调用,则必须以public修饰,但又不想让子类重写,就可以使用final修饰符。
7.如果希望父类的某个方法被子类重写,但不希望被其他类自由访问,则可以使用protected来修饰方法。
8.尽量不要在父类构造器中调用将要被子类重写的方法。

方法的重写

1.重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

2.重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

3.重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。

方法重写规则

重写遵循“两同两小一大”规则
两同: 方法名、形参列表相同
两小
子类方法返回值类型应比父类方法返回值类型更小或相等
子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等
一大
子类方法的访问权限应比父类方法访问权限更大或相等

上一篇下一篇

猜你喜欢

热点阅读