继承和方法重写

1. 继承

继承是Java中实现代码重用的重要手段之一。Java中只支持单根继承,即一个类只能有一个直接父类.。 子类与父类是is-a的关系,子类是父类 父子类信息编写原则: 父类中编写共有的属性和行为 子类中编写独有的属性和行为

  1. package com.qfedu.test1;
  2. /**
  3. * 父类:宠物类
  4. * 用于记录两个宠物共同有的属性 和 行为
  5. *
  6. * 子类与父类是is-a的关系 子类是父类 (狗是宠物,企鹅是宠物)
  7. * 父子类信息编写原则:
  8. * 父类中编写共有的属性和行为
  9. * 子类中编写独有的属性和行为
  10. * @author WHD
  11. *
  12. */
  13. public class Pet {
  14. private String name;
  15. private int health;
  16. private int love;
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public int getHealth() {
  24. return health;
  25. }
  26. public void setHealth(int health) {
  27. this.health = health;
  28. }
  29. public int getLove() {
  30. return love;
  31. }
  32. public void setLove(int love) {
  33. this.love = love;
  34. }
  35. public void print() {
  36. System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);
  37. }
  38. }
  1. package com.qfedu.test1;
  2. /**
  3. * 狗类
  4. * 名字
  5. * 健康值
  6. * 爱心值
  7. * 品种
  8. * 打印狗狗信息
  9. * @author WHD
  10. *
  11. */
  12. public class Dog extends Pet{
  13. private String strain;
  14. public String getStrain() {
  15. return strain;
  16. }
  17. public void setStrain(String strain) {
  18. this.strain = strain;
  19. }
  20. public Dog() {}
  21. }
  1. package com.qfedu.test1;
  2. /**
  3. * 企鹅类
  4. * 名字
  5. * 健康值
  6. * 爱心值
  7. * 性别
  8. * 打印信息
  9. * @author WHD
  10. *
  11. */
  12. public class Penguin extends Pet{
  13. private String sex;
  14. public String getSex() {
  15. return sex;
  16. }
  17. public void setSex(String sex) {
  18. this.sex = sex;
  19. }
  20. public Penguin() {}
  21. }
  1. package com.qfedu.test1;
  2. public class Test {
  3. public static void main(String[] args) {
  4. Dog dog = new Dog();
  5. dog.setName("大黄");// Pet继承而来的
  6. dog.setHealth(100);// Pet继承而来的
  7. dog.setLove(100); // Pet继承而来的
  8. dog.setStrain("哈士奇"); // Dog类编写的
  9. dog.print();
  10. // 调用从父类继承而来的print方法打印信息 发现以下两个问题:
  11. // 1.打印信息身份不准确
  12. // 2.打印信息不具体
  13. System.out.println("===============================================");
  14. Penguin p1 = new Penguin();
  15. p1.setName("大白");// Pet继承而来的
  16. p1.setLove(100);// Pet继承而来的
  17. p1.setHealth(100);// Pet继承而来的
  18. p1.setSex("雌"); // Penguin类编写的
  19. System.out.println(p1.getName());
  20. System.out.println(p1.getHealth());
  21. System.out.println(p1.getLove());
  22. System.out.println(p1.getSex());
  23. p1.print();
  24. }
  25. }

2. super关键字

super关键字:表示父类对象 可以访问,父类访问权限允许的 方法 属性 构造方法

  1. package com.qfedu.test2;
  2. /**
  3. * 父类:宠物类
  4. * 名字
  5. * 健康值
  6. * 爱心值
  7. *
  8. * super关键字:表示父类对象
  9. * 可以访问,父类访问权限允许的
  10. * 方法
  11. * 属性
  12. * 构造方法
  13. * @author WHD
  14. *
  15. */
  16. public class Pet {
  17. protected String name;
  18. protected int health;
  19. protected int love;
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. public int getHealth() {
  27. return health;
  28. }
  29. public void setHealth(int health) {
  30. this.health = health;
  31. }
  32. public int getLove() {
  33. return love;
  34. }
  35. public void setLove(int love) {
  36. this.love = love;
  37. }
  38. public void print() {
  39. System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);
  40. }
  41. }
  1. package com.qfedu.test2;
  2. /**
  3. * 狗类
  4. * 品种
  5. * 打印狗狗信息
  6. * @author WHD
  7. *
  8. */
  9. public class Dog extends Pet{
  10. private String strain;
  11. public String getStrain() {
  12. return strain;
  13. }
  14. public void setStrain(String strain) {
  15. this.strain = strain;
  16. }
  17. public Dog() {}
  18. public void printDog() {
  19. super.print();
  20. System.out.println("狗狗的品种是" + strain);
  21. }
  22. public Dog(String name,int health,int love,String strain) {
  23. this.strain = strain;
  24. super.name = name;
  25. super.health = health;
  26. super.love = love;
  27. }
  28. }
  1. package com.qfedu.test2;
  2. public class Test {
  3. public static void main(String[] args) {
  4. Dog dog = new Dog();
  5. dog.setName("大黄");
  6. dog.setHealth(100);
  7. dog.setLove(100);
  8. dog.setStrain("金毛");
  9. // dog.print();
  10. dog.printDog();
  11. System.out.println("===========================");
  12. Penguin p1 = new Penguin();
  13. p1.setName("大白");
  14. p1.setLove(100);
  15. p1.setHealth(100);
  16. p1.setSex("雌");
  17. p1.printPenguin();
  18. System.out.println("===========================");
  19. Dog dog1 = new Dog("小黑", 100, 100, "金毛");
  20. dog1.printDog();
  21. }
  22. }

super关键字:表示父类对象 构造方法 创建子类对象时,默认调用父类的无参构造方法 除非子类显式的调用父类的有参构造方法 子类必须调用父类的构造方法 无参或者有参必须调用一个

  1. package com.qfedu.test5;
  2. /**
  3. * 父类:宠物类
  4. * 名字
  5. * 健康值
  6. * 爱心值
  7. *
  8. * @author WHD
  9. *
  10. */
  11. public class Pet {
  12. protected String name;
  13. protected int health;
  14. protected int love;
  15. public String getName() {
  16. return name;
  17. }
  18. public void setName(String name) {
  19. this.name = name;
  20. }
  21. public int getHealth() {
  22. return health;
  23. }
  24. public void setHealth(int health) {
  25. this.health = health;
  26. }
  27. public int getLove() {
  28. return love;
  29. }
  30. public void setLove(int love) {
  31. this.love = love;
  32. }
  33. public Pet(String name,int health,int love) {
  34. this.name = name;
  35. this.health = health;
  36. this.love = love;
  37. }
  38. /**
  39. * 父类中推荐都提供无参 方便子类使用
  40. */
  41. public Pet() {}
  42. public void print() {
  43. System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);
  44. }
  45. }
  1. package com.qfedu.test5;
  2. /**
  3. * 狗类
  4. * 品种
  5. * 打印狗狗信息
  6. * @author WHD
  7. *
  8. */
  9. public class Dog extends Pet{
  10. private String strain;
  11. public String getStrain() {
  12. return strain;
  13. }
  14. public void setStrain(String strain) {
  15. this.strain = strain;
  16. }
  17. public void printDog() {
  18. print();
  19. System.out.println("狗狗的品种是" + strain);
  20. }
  21. /**
  22. * 因为父类的无参构造被覆盖了 所以Dog子类报错
  23. * 解决方案:编写有参构造调用父类的有参 不再调用无参
  24. * @param name
  25. * @param health
  26. * @param love
  27. * @param strain
  28. */
  29. public Dog(String name,int health,int love,String strain) {
  30. super(name, health, love);
  31. this.strain = strain;
  32. }
  33. }
  1. package com.qfedu.test5;
  2. /**
  3. * 企鹅类
  4. * 性别
  5. * 打印信息
  6. * @author WHD
  7. *
  8. */
  9. public class Penguin extends Pet{
  10. private String sex;
  11. public String getSex() {
  12. return sex;
  13. }
  14. public void setSex(String sex) {
  15. this.sex = sex;
  16. }
  17. public void printPenguin() {
  18. super.print(); // 继承自父类的方法 可以使用super加点 或者this加点 或者直接书写 方法名
  19. System.out.println("企鹅的性别是" + sex);
  20. }
  21. }

3. 方法重写

image.png

1.父子类之间的 2.方法名称相同 3.参数列表相同 4.访问权限不能严于父类 不能窄化父类的访问权限 5.返回值相同 或者是其子类 6.父类的静态方法可以被继承 但是不能被重写 非静态方法不能重写为静态方法 7.不能抛出比父类更多的异常

@Override注解 此注解可以用于子类的方法上 表示此方法为重写父类的方法 如果没有符合以上重写的规则 那么将编译报错

  1. package com.qfedu.test6;
  2. /**
  3. * 狗类
  4. * 品种
  5. * 打印狗狗信息
  6. * @author WHD
  7. *
  8. */
  9. public class Dog extends Pet{
  10. private String strain;
  11. public String getStrain() {
  12. return strain;
  13. }
  14. public void setStrain(String strain) {
  15. this.strain = strain;
  16. }
  17. /**
  18. * 方法重写
  19. * 1.父子类之间的
  20. * 2.方法名称相同
  21. * 3.参数列表相同
  22. * 4.访问权限不能严于父类 不能窄化父类的访问权限
  23. * 5.返回值相同 或者是其子类
  24. *
  25. * 6.父类的静态方法可以被继承 但是不能被重写 非静态方法不能重写为静态方法
  26. * 7.不能抛出比父类更多的异常
  27. */
  28. @Override
  29. public void print() {
  30. super.print();
  31. System.out.println("狗狗的品种是" + strain);
  32. }
  33. public static void m1() {
  34. }
  35. public Dog(String name,int health,int love,String strain) {
  36. super(name, health, love);
  37. this.strain = strain;
  38. }
  39. }

4.Object类

Object是所有的类的父类,所有的类将默认继承自此类 此类中提供了一些常用的方法,实际开发中我们经常重写这些方法

4.1 重写toString方法

我们直接打印一个对象将默认调用此对象的toString方法,返回值为包名类名+@+哈希值 如果我们不想要这个效果,可以重写toString方法

  1. package com.qfedu.test7;
  2. /**
  3. * 学生类
  4. * 名字
  5. * 年龄
  6. * @author WHD
  7. *
  8. */
  9. public class Student{
  10. private String name;
  11. private int age;
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public int getAge() {
  19. return age;
  20. }
  21. public void setAge(int age) {
  22. this.age = age;
  23. }
  24. public String toString() {
  25. String str = super.toString();
  26. return "Student[name=" + name + ",age=" + age + "]" + str;
  27. }
  28. public static void main(String[] args) {
  29. Student stu = new Student();
  30. stu.setName("赵四");
  31. stu.setAge(17);
  32. System.out.println(stu.getName());
  33. System.out.println(stu.getAge());
  34. System.out.println(stu); // 直接打印一个对象将调用从父类继承而来的toString方法
  35. System.out.println(stu.toString());
  36. }
  37. }