复学day09

继承

继承是类和类之间的一种关系,本质是对某一批类的抽象,从而实现更好的建模。其关键字为extend,意为“扩展”。

继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承了父类就会拥有父类的全部方法(属性要依据修饰词判断),用关键字extend表示。且java类中只有单继承,没有多继承(a extend A,b extend A,但是a extend B是不允许的)

ps:java中所有的类都默认直接或间接的继承Objcet类。

由于继承的出现,便引入了this、super关键字,这是避免父类和子类的方法或属性同名时引起混乱。使用this关键字意为使用本类方法亦或属性,使用super关键字意为使用父类方法亦或属性。

除此之外,在通过子类构造器构造子类对象时,其子类的无参构造会优先实现其父类的无参构造,代码如下:

public class Student extend Person{
    public Student(){
    super();//必须在第一个
    }
}
重写

在Java中的继承中,子类既可以隐藏和访问父类的方法,也可以覆盖继承父类的方法。相对于父类,子类可以定义新的特征,当子类需要修改父类的一些方法进行扩展,增大功能,程序设计者常常把这样的一种操作方法称为重写,也叫称为覆写或覆盖。

所谓方法的重写是指子类中的方法与父类中继承的方法有完全相同的返回值类型、方法名、参数个数以及参数类型。

重写都是方法的重写,与属性无关

在重写方法时,应注意以下规则:

1、父类方法的参数列表必须完全与子类重写的方法的参数列表相同,否则不能称其为重写,其本质为重载

2、父类的返回值类型必须与子类重写的方法返回值类型相同,否则不能称其为重写而是重载。

3、子类重写的方法不能拥有比父类方法更加严格的访问权限(当父类方法的权限修饰词为private时,该方法只能被自己类访问,即子类不能重写。当父类方法修饰词为public时,子类方法权限修饰词必须>=public)(会出现子类向上转型变成父类,然而不能调用子类方法的情况)

4、子类重写的方法抛出的异常应该少于或等于父类方法抛出的异常

public class Fu{
   public String test(){
       System.out.println("父类")
   }
}
public class Zi extend Fu{
    @override
    public String test(){
        System.out.println("子类")
    }
}

这里重载和重写可能会产生混淆,重写是发生在子父类之间的子类中,而重载是在一个类中参数不同同名方法的实现

PS:阻止继承,用final修饰词修饰类

多态

在Java程序语言的设计中,对象变量是多态的。有一个用来判断是否应该设计成继承关系的简单规则,就是“is-a”规则,它表明子类的每个对象也是父类的对象。例如,每个经理都是雇员,所以将Manage类设计为Employee类的子类是显然易见的。

Employee e;
e = new Employee(...);
e = new Manage(...);

如上述代码所示,e这个对象变量是多态的。

既然对象是多态的,那么对象在调用方法时就应清晰理解其原理

//一个对象的实现类型是确定的,即 new Student();
//但是指向的引用类型却是不一定的,s2便是父类的引用指向子类
Student s1 = new Studtent();
Person s2 = new Student();

s1.eat();
s2.eat();

s1.school();
s2.school();//方法会异常,因为school()为Student类的特有方法,s2为Person类

在每次调用方法时都要进行通过参数、方法名检索,时间开销会很大。因此虚拟机预先为每个类创建了一个放发表(method table),其中列出了所有方法的签名和实际调用的方法。所以,上述方法实现步骤为:

1、首先,虚拟机提取s1/s2的实际类型放发表。

2、接下来,虚拟机搜索定义eat/school签名的类,此时,虚拟机便已经知道应该调用哪个方法

3、方法调用。

(该部分为Java核心技术卷1对多态方法调用时的总结,感觉译文有点点问题)

普遍教程这段讲解为:编译看左,执行看右。即右边的new的不影响左边的属性,仅在执行方法时优先考虑右边。

抽象类

从子父类这种自下而上的继承层次上移,位于上层的类更具有通用性,这边产生了抽象类。(该部分并不常用,后续接口、实现类更为重点)

其关键字为abstract。抽象类并不能通过new关键字生成实体类,只能通过实体类继承抽象类实现。

public abstract class Fx(){
    public abstract void say(){
    }
    public void eat(){
        System.out.print("eat");
    }
}

上述变为一个抽象类Fx;其中say()方法为抽象方法,并没有方法体,起到约束作用,若某一实体类继承了某抽象类,那么该实体类则必须重写抽象类中的抽象方法。

接口

与类不同,接口就是规范,定义的是一组规则,体现的思想是“如果你是...则必须能...”的思想。其本质是契约。关键字为interface。

public interface User{
    //接口中的所有定义都是抽象的 public abstract
    void add(String name);
}

接口不能通过new关键字实例化(没有构造方法),接口的实现均是通过实现类实现!关键字为implement

public class UserService implement User{
    @override
    public void add(String name){
        ...
    }
}

接口为纯约束,且一个实现类可以继承多个接口

posted @ 2020-11-18 19:15  何安生  阅读(106)  评论(0)    收藏  举报