2020-12-02

Java基础之:OOP——继承

Java基础之:OOP——继承

面向对象编程OOP(Object Oriented Programming)的三大特征之二:继承

首先看一个案例,分别创建小学生与研究生类,输出他们的信息:

小学生类:

public class Pupil { //小学生类​ String name; double score; public String getName() {  return name; } public void setName(String name) {  this.name = name; } public double getScore() {  return score; } public void setScore(double score) {  this.score = score; } public void testing() {  System.out.println("小学生考语文..."); } public void showScore() {  System.out.println("学生名" + name + " 成绩=" + score); }}

研究生类:
public class Graduate { //研究生​ String name; double score; public String getName() {  return name; } public void setName(String name) {  this.name = name; } public double getScore() {  return score; } public void setScore(double score) {  this.score = score; } public void testing() {  System.out.println("研究生考的是微积分..."); } public void showScore() {  System.out.println("学生名 " + name + " 成绩=" + score); }}

可以看到 在小学生类与研究生类中 ,有大量的内容是重复的,只有 testing() 方法不同。所以我们可以将它们两个类中共同的属性或方法抽象出来创建一个Student类,再继承Student。

继承介绍

继承可以解决代码的复用性问题,让编程更解决我们人类的思维逻辑,多个类出现相同的属性/方法时,可以将这些属性/方法抽象出来,放在一个父类中来定义,所有的子类都不需要再定义这些属性/方法,只需要继承(extends)父类即可。

继承语法

class 子类名 extends 父类名 {}

说明:

1) 子类就会自动拥有父类定义的属性和方法

2) 父类又叫 超类,基类。

3) 子类又叫派生类。

简单案例

对上面的小学生类和研究生类进行改进。

Student类:

public class Student { //父类​ String name; double score; public String getName() {  return name; } public void setName(String name) {  this.name = name; } public double getScore() {  return score; } public void setScore(double score) {  this.score = score; } public void showScore() {  System.out.println("学生名 " + name + " 成绩=" + score); }}

Pupil类:

public class Pupil extends Student { //小学生类, 子类​ public void testing() {  System.out.println("小学生考语文..."); } }​ 

Graduate类:

public class Graduate extends Student{ //研究生 子类​ public void testing() {  System.out.println("研究生考的是微积分..."); } }

继承优点

  1. 代码复用性提高了。

  2. 代码的扩展性和维护性提高了。

继承使用细节与注意事项

  1. 子类继承了所有的属性和方法,只是私有的属性不能直接访问,需要通过公共方法进行访问。(封装的体现)

  2. 子类没有继承父类的构造器,但在子类的构造器中必须调用父类的构造器,完成父类的初始化。(例:肯定是先有爷爷再有爸爸最后有儿子)

  3. 当创建子类时,不管你使用子类的哪个构造方法,默认情况下总会去调用父类的无参构造函数,如果父类没有提供无参构造函数,则必须在子类的构造函数中用 super 去指定使用父类的哪个构造函数完成对父类的初始化工作,否则,编译不会通过。

  4. 如果希望指定调用父类的某个构造方法,需要使用super关键字显式调用。

    1. 无参构造器:super();

    2. 有一个参数:super(参数);

    3. 要注意super在使用时,需要放在方法体的第一句位置。

  5. super() 和 this() 都只能放在构造方法句首,因此这两个方法不能共存在一个方法中

  6. java中所有的类都是Object类的子类

  7. 子类最多只能有一个直接父类,也就是只能继承一个父类。(若需要A类继承B类和C类,则A继承B,B继承C)。

  8. 父类构造器的调用不限于直接父类!将一直往上追溯直到Object类。同样的,若子类调用父类提供的方法,也不限于直接父类。

简单案例

import java.util.ArrayList;​public class ExtendsDetail {​ public static void main(String[] args) {  BB bb = new BB();  bb.m1(); }}​class DD { public DD() {  System.out.println("DD() 被调用"); }}​// 子类继承了所有的属性和方法,只是私有的属性不能直接访问,需要通过公共的方法去访问class AA extends DD { // 属性 public int n1 = 10; protected int n2 = 20; int n3 = 30; private int n4 = 40;  public int getN4() {  return n4; } // public AA() {//  System.out.println("AA() 构造器..");// }  public AA(String name) {  }   public AA() {    }   public AA(int num) {   //super();  }}​//类的BB继承 ctrl+tclass BB extends AA { //子类BB 继承 AA public void m1() {  System.out.println(n1 + " " + n2 + " " + n3 + " " /*+ n4 */);  System.out.println(getN4()); }  //子类没有继承父类的构造器,但必须调用父类的构造器, 完成父类的初始化. //至于调用父类的哪个构造器,无所谓,但是一定要调用一个 public BB() {  //默认有一句话 super(), 父类的无参构造器    //如果希望指定去调用父类的某个构造方法,则显示的调用一下  //super在使用时,需要放在方法体的第一句位置  //super() 和 this() 都只能放在构造方法句首,因此这两个方法不能共存在一个方法中  super(10);  System.out.println("BB() 构造器.."); } } 

  

内存分析案例

public class ClassTest { public static void main(String[] args) {  son son = new son(); }}​class Guandpa { private String name;  public Guandpa(String name) {  super(); //指向 Object();  this.name = name; }​ public Guandpa() {  //默认存在super(); 即使不显式的写出  this.name = "爷爷"; }  public void show() {  System.out.println("Guandpa:" + name); }}​class father extends Guandpa{ private String name;​ public father(String name) {  super();  this.name = name; }​ public father() {  super();// 指向 Guandpa();  this.name = "父亲"; }  public void show(){  System.out.println("father"+name); } }​class son extends father{ private String name;  public son(String name) {  super();   //默认存在super();即使不显式的写出。  //当我们在father类中 无参构造方法被覆盖时, son子类的构造方法就会报错。  //因为son子类在构造时 ,会首先调用super();   this.name = name; }​ public son() {  super(); //指向 father();  this.name = "儿子"; }  public void f1() {  show(); }}

  

super关键字

super代表父类的引用,用于访问父类的属性、方法、构造器

基本语法

  1. 访问父类的属性 , 不能访问父类的private属性 [案例] super.属性名;

  2. 访问父类的方法,不能访问父类的private方法

    super.方法名(参数列表);

  3. 访问父类的构造器(这点前面用过): super(参数列表);只能放在构造器的第一句,而且只能出现一句

细节说明

  1. 调用父类的构造器 (分工明确, 父类属性由父类初始化,子类的属性由子类初始化)

  2. 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果!

  3. super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类中都有同名的成员,使用super访问遵循就近原则。A->B->C

super与this

继承应用案例1

为了代码方便阅读这里将各个类写在了一起,但在实际开发中应该保证一个类一个文件,所有类在同一个包下。

/** * * 编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息 * 编写PC子类,继承Computer类,添加特有属性【品牌brand】 编写NotePad子类,继承Computer类,添加特有属性【演示color】 * 编写Test类,在main方法中创建PC和NotePad对象,分别给对象中特有的属性赋值, * 以及从Computer类继承的属性赋值,并使用方法并打印输出信息 * */public class Test { public static void main(String[] args) {  PC pc = new PC("intel_i9", "16GB", "1TB", "PCbrand");  NotePad notePad = new NotePad("cpu", "8GB", "128GB", "NotePadcolor");    System.out.println(pc.getDetails());  System.out.println(notePad.getDetails()); }}​//编写Computer类,包含CPU、内存、硬盘等属性,getDetails方法用于返回Computer的详细信息class Computer { //private + set & get 方法,体现封装 private String CPU; private String memory; private String disk;  public String getCPU() {  return CPU; }​ public void setCPU(String cPU) {  CPU = cPU; }​ public String getMemory() {  return memory; }​ public void setMemory(String memory) {  this.memory = memory; }​ public String getDisk() {  return disk; }​ public void setDisk(String disk) {  this.disk = disk; }​  public String getDetails() {  return "Computer [CPU=" + CPU + ", memory=" + memory + ", disk=" + disk + "]"; }​ public Computer(String cPU, String memory, String disk) {  super();  CPU = cPU;  this.memory = memory;  this.disk = disk; }​ public Computer() {  super(); }  }​//编写PC子类,继承Computer类,添加特有属性【品牌brand】class PC extends Computer { private String brand; //private + set & get 方法,体现封装  public String getBrand() {  return brand; }​ public void setBrand(String brand) {  this.brand = brand; }​ @Override public String getDetails() {  return super.getDetails() + "\nPC [brand=" + brand + "]"; }​ public PC(String cPU, String memory, String disk, String brand) {  super(cPU, memory, disk);  this.brand = brand; }  }​//编写NotePad子类,继承Computer类,添加特有属性【演示color】class NotePad extends Computer { private String color; //private + set & get 方法,体现封装  public String getColor() {  return color; }​ public void setColor(String color) {  this.color = color; }​ @Override public String getDetails() {  return super.getDetails() + "\nNotePad [color=" + color + "]"; }​ public NotePad(String cPU, String memory, String disk, String color) {  super(cPU, memory, disk);  this.color = color; } }

继承应用案例2

为了代码方便阅读这里将各个类写在了一起,但在实际开发中应该保证一个类一个文件,所有类在同一个包下。

/** * 定义一个ManKind类: 成员变量int sex和int salary; 要求加上两个参数有参构造 * 方法void manOrWomen():根据sex的值显示"man"(sex==1)或者"women"(sex==0); * 方法void employeed():根据salary的值显示"no job"(salary==0)或者" job"(salary!=0)。 * 定义类Kids继承ManKind,并包括成员变量int yearsOld; 方法printAge()打印yearsOld的值。 * 在Kids类的main方法中实例化Kids的对象someKid,用该对象访问其父类的成员变量及方法。 */public class HomeWork {​ public static void main(String[] args) {  Kids kids = new Kids(2,-100,18);    kids.manOrWomen();  kids.employeed();  kids.printAge();​ }​}​class ManKind { private int sex; private int salary;  public int getSex() {  return sex; }​ public void setSex(int sex) {  this.sex = sex; }​ public int getSalary() {  return salary; }​ public void setSalary(int salary) {  this.salary = salary; }​ // 方法void manOrWomen():根据sex的值显示"man"(sex==1)或者"women"(sex==0); public void manOrWomen() {  if (sex == 1) {   System.out.println("man");  } else{   System.out.println("women");  } }​ // 方法void employeed():根据salary的值显示"no job"(salary==0)或者" job"(salary!=0)。 public void employeed() {  if (salary == 0) {   System.out.println("no job!");  } else {   System.out.println("job!");  } }​ public ManKind(int sex, int salary) {  super();  if(sex != 0 && sex !=1) {   System.out.println("性别输入内容错误,0表示女,1表示男!");   this.sex = 0;  }else {   this.sex = sex;  }  if (salary < 0) {   System.out.println("输入工资错误,默认值1000");   this.salary = 1000;  } else {   this.salary = salary;  } }​ public ManKind() {  super(); }​}​//定义类Kids继承ManKind,并包括成员变量int yearsOld; 方法printAge()打印yearsOld的值。 class Kids extends ManKind{ private int yearsOld;  public int getYearsOld() {  return yearsOld; }​ public void setYearsOld(int yearsOld) {  this.yearsOld = yearsOld; }​ public void printAge() {  System.out.println("年龄:"+yearsOld); }​ public Kids(int sex, int salary, int yearsOld) {  super(sex, salary);  this.yearsOld = yearsOld; }  public static void main(String[] args) {   //在另外一个非public类中 也有一个main时,点击Run As 会询问执行哪一个main  Kids kids = new Kids(1,2000,18);  kids.setSex(0);  kids.manOrWomen();  kids.employeed();  kids.printAge(); }}

  

 

 









原文转载:http://www.shaoqun.com/a/494627.html

预售:https://www.ikjzd.com/w/889

五洲会:https://www.ikjzd.com/w/1068

oklink:https://www.ikjzd.com/w/1362


Java基础之:OOP——继承面向对象编程OOP(ObjectOrientedProgramming)的三大特征之二:继承首先看一个案例,分别创建小学生与研究生类,输出他们的信息:小学生类:publicclassPupil{//小学生类​Stringname;doublescore;publicStringgetName(){returnname;}publicvoidsetName(String
patpat:patpat
数魔跨境:数魔跨境
如何降低wish的退款率:如何降低wish的退款率
离地王大厦最近的地铁站叫什么?:离地王大厦最近的地铁站叫什么?
九寨沟民俗文化—领地酒庄 :九寨沟民俗文化—领地酒庄

No comments:

Post a Comment