继承

一个类 可以 继承自 另一个类;

派生的类(子类)继承父类的方法和数据成员;

关键字:子类 extends 父类。

  1. public class 继承 {
  2. public static void main(String[] args) {
  3. 王思聪 a = new 王思聪();
  4. System.out.println(a.money);
  5. a.show();
  6. }
  7. }
  8. class 王健林 {
  9. double money = 188.88;
  10. void show() {
  11. System.out.println("不差钱");
  12. }
  13. }
  14. class 王思聪 extends 王健林 {
  15. }

设计示例

继承主要解决的问题是:共性抽取。

继承的特点:

|--子类可以拥有父类的“内容”

|--子类可以拥有自己的“内容”

卡车和巴士都是汽车,它们共有的特征来自汽车,他们也可以有自己的特征:

  1. public class 继承2 {
  2. public static void main(String[] args) {
  3. }
  4. }
  5. class 汽车 {
  6. private int wheels;
  7. public int getWheels() {
  8. return wheels;
  9. }
  10. public void setWheels(int wheels) {
  11. this.wheels = wheels;
  12. }
  13. // ------------------------
  14. public void 开车() {
  15. System.out.println("开车了");
  16. }
  17. public void 刹车() {
  18. System.out.println("刹车");
  19. }
  20. }
  21. class 卡车 extends 汽车 {
  22. private int carryingCapacity;
  23. public int getCarryingCapacity() {
  24. return carryingCapacity;
  25. }
  26. public void setCarryingCapacity(int carryingCapacity) {
  27. this.carryingCapacity = carryingCapacity;
  28. }
  29. // ------------------------
  30. public void 挂箱() {
  31. System.out.println("挂箱");
  32. }
  33. }
  34. class Bus extends 汽车 {
  35. private int seatings;
  36. public int getSeatings() {
  37. return seatings;
  38. }
  39. public void setSeatings(int seatings) {
  40. this.seatings = seatings;
  41. }
  42. // ------------------------
  43. public void 报站(String str站名) {
  44. System.out.println(str站名 + "已到");
  45. }
  46. }

继承控制

protected:继承即可用,即使不在同一个包中

private:不给继承

this和super

this:自己的

super:父类的

|-|-super():父类构造方法

|-|-super.XXX:父类的成员(方法或变量)

  1. public class This_and_Super {
  2. public static void main(String[] args) {
  3. S _s = new S();
  4. _s.m();// 直接通过子类对象,调用的是子类的方法
  5. _s.newNethod();
  6. }
  7. }
  8. class F {
  9. protected int a = 1;
  10. protected void m() {
  11. System.out.println("F");
  12. }
  13. }
  14. class S extends F {
  15. protected int a = 99;
  16. protected void m() {
  17. System.out.println("S");
  18. }
  19. protected void newNethod() {
  20. System.out.println(super.a);
  21. System.out.println(this.a);
  22. System.out.println(a);// 直接调用,是自己的值
  23. // ---------
  24. super.m();
  25. this.m();
  26. m();// 直接调用,是自己的方法
  27. }
  28. }

super():再论构造方法

super必须有,不写也默认,必须第一句,只能有一个

​ (1)默认调父类的无参构造方法,直到显式调用父类的有参构造方法。

​ 详解:无论子类构造方法带不带参数,默认都是执行父类的无参构造方法。【隐藏一句代码:super()】

如果非要执行父类带参构造方法的话,使用super(参数列表)。

​ (2)super(父类构造方法)只能放在构造方法中,且必须放在第一句,因此也不能多次调用父类构造方法。

测试:

  1. public class 构造顺序 {
  2. public static void main(String[] args) {
  3. new S();
  4. new S(1);
  5. new S(1L);
  6. }
  7. }
  8. class F {
  9. F() {
  10. System.out.println("父类构造方法");
  11. }
  12. F(int a) {
  13. System.out.println("父类构造方法(带参)");
  14. }
  15. }
  16. class S extends F {
  17. S() {
  18. System.out.println("子类构造方法\n");
  19. }
  20. S(int a) {
  21. System.out.println("子类构造方法(带参)\n");
  22. }
  23. S(long a) {
  24. super(1);
  25. System.out.println("子类构造方法2(带参),显示调用父类的带参构造方法\n");
  26. }
  27. }

父类构造方法

子类构造方法

父类构造方法

子类构造方法(带参)

父类构造方法(带参)

子类构造方法2(带参),显示调用父类的带参构造方法

this()

this(...)也可以调用自己的其它构造方法,也必须放在第一句,一个构造方法中只能写一句。

  1. class S2 extends F {
  2. S2() {
  3. this(100);
  4. }
  5. S2(int a) {
  6. this(100, 200);
  7. }
  8. S2(int a, int b) {
  9. }
  10. }

思考题:总结super和this的用法

重写·Override

Override:方法重写、方法覆盖。

子类可以重新定义继承自父类的方法。子类方法中,可通过super来调用父类的方法。

  • 两同:方法名相同,形参列表相同
  • 两不大:返回类型不比父类大(大手大脚败家子),异常不比父类大(不得扩大范围)
  • 一不小:访问权限不比父类小(不得废公为私)

  1. public class 重写 {
  2. public static void main(String[] args) {
  3. Ostrich os = new Ostrich();
  4. os.twitter();
  5. os.fly();
  6. }
  7. }
  8. class Bird {
  9. public void twitter() {
  10. System.out.println("wakuwaku");
  11. }
  12. public void fly() {
  13. System.out.println("飞");
  14. }
  15. }
  16. // 鸵鸟类
  17. class Ostrich extends Bird {
  18. @Override// 不写也是重写,写了会做检测,若方法在父类不存在将报错
  19. public void fly() {
  20. super.fly();
  21. System.out.println("?并不会");
  22. }
  23. }

wakuwaku



?并不会

返回类型不比父类大(注:Object是String的父类)

访问权限不比父类小(尧→舜→禹,启结束了禅让制度。)

  1. class Bird {
  2. public Object twitter() {
  3. return null;
  4. }
  5. public String fly() {
  6. return null;
  7. }
  8. }
  9. // 鸵鸟类
  10. class Ostrich extends Bird {
  11. public String twitter() {// 父类是Object,子类是String,没问题
  12. return null;
  13. }
  14. @Override// 父类返回类型String,改为Object
  15. public Object fly() {// The return type is incompatible with Bird.fly()
  16. return null;
  17. }
  18. }
  19. // 鸽子类
  20. class Pigeon extends Bird {
  21. @Override
  22. private String fly() {// 父类是public,改为private
  23. // Cannot reduce the visibility of the inherited method from Bird
  24. return null;
  25. }
  26. }

重写的应用场景:

对于已经存在的类,尽量不要进行代码修改,而是派生一个新的子类,对响应的方法进行重写。

final(不准修改)

Final修饰类:该类不可被继承(比如String类)

Final修饰方法:该方法不能被重写

Final修饰变量:不能被重新赋值

Java里的“常量”:

  1. public static final int CHANG_LIANG = 10;

继承的坏处

继承是实现类复用的重要手段,但是继承会破坏封装。

每个类都应该封装其内部信息和实现细节,仅暴露必要的方法给其他类使用。但子类可以直接访问父类的内部信息,甚至可以重写父类的方法,这增加了子类和父类的耦合度,破坏了封装。

设计父类时,应遵循以下原则:

  • 尽量将父类的成员变量设置为private。
  • 尽量缩小方法的访问权限,能私有尽量不要共有。
  • 不希望被子类重写的方法设置为final。
  • 不要在父类的构造方法中调用被子类重写的方法。

​ 下例代码中,父类A的构造方法,该方法调用了被重写的method()方法,因为是先执行父类构造方法,而其调用的method()方法是被子类重写的,此时并没有变量s,因此s为null。

  1. class A {
  2. public A() {
  3. System.out.println("A的构造方法");
  4. method();
  5. this.method();
  6. }
  7. public void method() {
  8. System.out.println("A method");
  9. }
  10. }
  11. class B extends A {
  12. public String s = "子类变量";
  13. public void method() {
  14. System.out.println("B method:" + s);
  15. }
  16. }
  17. public class TestInstanceOf {
  18. public static void main(String[] args) {
  19. B b = new B();
  20. }
  21. }

Java基础教程——继承的更多相关文章

  1. Java基础教程(18)--继承

    一.继承的概念   继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...

  2. Java基础教程:注解

    Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...

  3. Java基础教程:泛型基础

    Java基础教程:泛型基础 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚 ...

  4. Java基础教程:反射基础

    Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...

  5. Java基础教程:面向对象编程[2]

    Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...

  6. Java基础教程:面向对象编程[1]

    Java基础教程:面向对象编程 内容大纲 Java语言概述 Java语言特点 1.Java为纯面向对象的语言,它能够直接反映现实生活中的对象.总之,Everything is object! 2.平台 ...

  7. Java基础教程:HashTable与HashMap比较

    Java基础教程:HashTable与HashMap比较 1.  关于HashMap的一些说法: a)  HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体.HashMap的底层结 ...

  8. Java基础教程:面向对象编程[3]

    Java基础教程:面向对象编程[3] 内容大纲 基础编程 获取用户输入 java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入.我们可以查看Ja ...

  9. Java基础教程:内部类

    Java基础教程:内部类 内部类 内部类,是指在一个类的内部定义的类.就像下面这样: public class EnclosingClass {   . . .   public class Nest ...

随机推荐

  1. Spring入门-----------------属性注入和对象注入

    属性注入即通过setter方法注入bean的属性或依赖对象. 属性注入使用<property>元素,使用name属性指定bean的属性的名称,value属性或<value>子节 ...

  2. 如何安装一个高可用K3s集群?

    作者介绍 Janakiram MSV是Janakiram & Associates的首席分析师,也是国际信息技术学院的兼职教师.他也是Google Qualified Developer.亚马 ...

  3. CodeForces 1426F Number of Subsequences

    题意 给定一个长度为 \(n\) 的串,只包含 abc 和通配符.通配符可以替换 abc 的一个.求所有得到的字符串中子序列 abc 出现的次数,对 \(10^9+7\) 取模. \(\texttt{ ...

  4. LTE DTU和4G DTU有什么不同

    其实4G DTU和LTE DTU从本质上来说是没有什么区别的,只是使用的运营商不同,设备的编号会有不同,都是属于DTU设备. LTE是baiLong Term Evolution(长期演进)的缩写.3 ...

  5. 03 . Gin+Vue开发一个线上外卖应用(用户数据创建,插入,跨域处理)

    功能和背景介绍 在项目的登录功能中,如果在登录时发现用户名和密码在用户表中不存在,会自动将用户名和密码保存在用户表中,创建一个新的用户. 因此,除了使用手机号和验证码登录以外,还支持使用用户名.密码进 ...

  6. 2. DRF 认证、权限、限流、分页、过滤、序列 化

    2.1 user/urls.py   ModelViewSet注册路由三部曲 from django.urls import include, path from user import views ...

  7. Flask常用API

    Flask常用API 1.os ​ 拼接路径:pathname = os.path.join(basepath, filename) 获得文件名后缀:suffix = os.path.splitext ...

  8. Javasript中this指向问题和改变this指向的方法

    在学习javascript中我们往往会被this的指向问题弄的头昏转向,今天我们就来学习一下this的指向问题,和改变this指向的方法. 一.this的指向问题 在学习this的指向问题之前我们需要 ...

  9. 【转载】Apriori

    通过这个博客学习:数据挖掘十大算法(四):Apriori(关联分析算法) 代码也是摘自上面博客,对照代码理解理论部分可能更加有助于对该算法的理解 from numpy import * # 构造数据 ...

  10. HTML生成横向的PDF

    HTML生成PDF请参照:https://www.cnblogs.com/yunfeiyang-88/p/10984740.html 如要生成横向的PDF:在html模板的style标签里面加入@pa ...