类的继承和super,final关键字的使用(JAVA)

目录

继承

super 

 子类的构造方法

final


继承

所有的OOP语言都会有三个特征:

  1. 封装(点击可跳转)
  2. 继承
  3. 多态(点击可跳转)

为什么会有继承呢?可以先看下面的例子:

7522cad7485b4834a3a2e386d34ee273.png

        上面这两个类中的代码很相似因为它们只有最后一个方法不同其它的都相同,这样定义不但导致代码冗余而且非常麻烦。而在OOP语言中继承就是专门用来进行共性抽取,实现代码复用。


继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性的基础上进行扩展,增加新功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用。

在JAVA中要实现继承需要借助extends关键字。

修饰符 class 子类 extends 父类 {
// ...
}

此时我们在看再面的例子老师和学生都属于人这个大类,那么我们就可以单独定义一个People类来将他们相同的属性和方法放在一起,然后由学生类和老师类分别继承人这个大类:

class People{
    public String name;
    public int age;
    public void speak(){
        System.out.println(this.name+"正在说话");
    }
}

class Teacher extends People{
    public void work(){
        System.out.println(this.name+"正在教书");
    }
}

class Student extends People{
    public void study(){
        System.out.println(this.name+"正在学习");
    }
}
public class Test {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.name = "zhangsan";
        teacher.age = 24;
        teacher.speak();
        teacher.work();
        System.out.println("==========");
        Student student = new Student();
        student.name = "xiaoming";
        student.age = 15;
        student.speak();
        student.study();
    }
}

5ef2fe03163f42868d1740b38f0f7539.png

 注意:子类会将父类中的成员变量或者成员方法继承到子类中。

那么现在又有一个新问题如果子类中有和父类相同的属性或方法那系统会怎么办?

class People{
    public String name;
    public int age = 25;
    public void speak(){
        System.out.println(this.name+"正在说话");
    }
}

class Teacher extends People{
    public int age = 20;
    public void work(){
        System.out.println(this.name+"正在教书"+"今年"+this.age);
    }
}

public class Test {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.name = "zhangsan";
        teacher.work();

    }
}

此时父类和子类都有age属性代码运行后可以看到使用的是子类的属性。 

ef0faced344048e39fc2c45b936895bf.png

 总结:

  1. 通过子类对象访问父类与子类中属性时,优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。
  2. 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
  3. 通过子类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,如果没有则报错;

就算父类中有private修饰的属性或方法子类也会将它继承下来但是无法访问。

973fd08d74a44515b1f3d18379b89441.png


super 

在上面的例子中出现了一个新的关键字super。那么super关键字是干什么的?

该关键字主要作用:在子类方法中访问父类的成员。

class People{
    public String name;
    public int age = 25;
    public void speak(){
        System.out.println(this.name+"正在说话");
    }
}

class Teacher extends People{
    public int age = 20;
    public void work(){
        System.out.println(this.name+"正在教书"+"今年"+super.age);
    }
}

public class Test {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.name = "zhangsan";
        teacher.work();

    }
}

因为父类和子类都有age属性此时如果想访问父类的属性就可以通过super关键字 ,super+.可以访问父类的属性和方法。(下文会为大家介绍super的第三种使用方法)。

2c369325445f42148a42e2c9d1015318.png
 

 子类的构造方法

此时如果父类有带参数的构造方法那么系统将会报错。

1e896df3f3044699a1d49138eaf45205.png

当父类中加入了含有两个参数构造方法之后代码就会报错。

接下来就为大家介绍一下super关键字的第三种使用方法:

super();

它可以调用父类的构造方法。

注:它必须放在构造方法的第一行。

因为实例化对象时有两个比较重要的步骤:

  1. 为对象分配内存;
  2. 调用合适的构造方法。

上面的代码在我们自己写了有参构造方法之后报错的原因就是子类的构造方法没有调用父类的构造方法。(当我们自己写了构造方法后系统就不会再为我们提供构造方法了,而子类对象构造时,需要先调用父类构造方法,然后再执行子类的构造方法。当我们没有写构造方法时系统会默认调用如下的构造方法:657a43318f744aca93b424d574e06fab.png, 我们只写了有参构造,所以系统就会因为找不到无参构造而报错,此时就需要我们自己进行调用:773dd6f18b064910998b240ec4edc236.png

子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整。

注意:

  1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法;
  2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败;
  3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句;
  4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现。
     

final

在JAVA中只支持以下几种继承方式:

  • 单继承;
  • 多层继承;
  • 不同类继承同一个类。

一般我们不希望出现超过三层的继承关系继承层次如果继承层次太多太复杂, 就需要考虑对代码进行重构了。

那我们应该如何阻止别人不让他们进行继承呢?

JAVA中提供了final关键可以用来修饰变量、成员方法以及类。

  • 修饰变量或字段,表示常量(即不能修改)
  • 修饰类:表示此类不能被继承
  • 修饰方法:表示该方法不能被重写

我们只要在不想被继承的类的前面用final修饰就可以了:

f4034606920544c397843c36506feeee.png

继承层次上代码的初始化顺序:

  1. 父类静态
  2. 子类静态
  3. 父类实例
  4. 父类构造
  5. 子类实例
  6. 子类构造

  • 27
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
Java语言中的关键字是指具有特殊含义的单词,这些单词在Java程序中具有特定的用途,不能作为标识符或变量名使用Java中共有50个关键字,其中包括48个保留关键字和2个特殊关键字。 以下是Java中的各种关键字: 1. abstract:用于定义抽象和抽象方法。 2. assert:用于调试程序时进行断言判断,如果条件不成立将会抛出AssertionError异常。 3. boolean:用于定义布尔型变量,只能取值true或false。 4. break:用于跳出循环语句。 5. byte:用于定义字节型变量,取值范围为-128到127。 6. case:用于在switch语句中匹配选项。 7. catch:用于捕获异常。 8. char:用于定义字符型变量。 9. class:用于定义。 10. const:Java虽然保留了此关键字,但并没有使用,因此不能用于定义常量。 11. continue:用于跳过循环中的某个迭代。 12. default:用于switch语句中的默认选项。 13. do:用于定义do-while循环。 14. double:用于定义双精度浮点型变量。 15. else:用于if语句中条件不成立时执行的代码块。 16. enum:用于定义枚举型。 17. extends:用于继承一个或实现一个接口。 18. final:用于定义常量或不可变的变量,或者修饰、方法、变量等,表示其不可再被继承、重写或修改。 19. finally:用于定义无论是否有异常发生都需要执行的代码块。 20. float:用于定义单精度浮点型变量。 21. for:用于定义for循环。 22. goto:Java虽然保留了此关键字,但并没有使用,因此不能跳转到标签。 23. if:用于定义条件语句。 24. implements:用于实现一个接口。 25. import:用于导入其他的定义。 26. instanceof:用于判断一个对象是否属于某个或实现了某个接口。 27. int:用于定义整型变量。 28. interface:用于定义接口。 29. long:用于定义长整型变量。 30. native:用于调用本地方法。 31. new:用于创建一个对象。 32. package:用于定义包。 33. private:用于定义私有成员,只能在当前中访问。 34. protected:用于定义受保护的成员,只能在当前及其子和同一个包中访问。 35. public:用于定义公共成员,可以被任何访问。 36. return:用于从方法中返回值。 37. short:用于定义短整型变量。 38. static:用于定义静态成员,只有一个拷贝,可以通过名直接访问。 39. strictfp:用于声明浮点数计算具有严格的规范化行为。 40. super:用于引用父的成员。 41. switch:用于定义switch语句。 42. synchronized:用于定义同步方法或同步代码块。 43. this:用于引用当前对象。 44. throw:用于抛出异常。 45. throws:用于声明方法可能抛出的异常。 46. transient:用于声明不需要持久化的变量。 47. try:用于定义异常处理代码块。 48. void:用于定义无返回值的方法。 49. volatile:用于声明变量是易变的,即每次访问都需要从主存中读取。 50. while:用于定义while循环。 以上就是Java中的各种关键字,这些关键字Java程序中起着非常重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值