当前位置: 首页 > news >正文

学习笔记——《Java面向对象程序设计》-继承

参考教材:

Java面向对象程序设计(第3版)微课视频版 清华大学出版社

1、定义子类

class 子类名 extends 父类名{......
}如:
class Student extends People{......
}

    (1)如果一个类的声明中没有extends关键字,这个类被系统默认为是Object的子类。Object是java.lang包中的类。

(2)除了Object类,任何(子)类有且仅有一个父类。

如 class Student extends People,Person语法错误。

2、子类的继承性

(1)类可以有两种重要的成员:成员变量和成员方法。

 子类中的成员变量或方法有一部分是子类自己声明的;另一部分是从父类继承的。

(2)什么叫继承呢?

子类继承父类的成员变量:像在子类中直接声明,可以被子类中自己定义的任何实例方法操作;

子类继承父类的方法:像在子类中直接声明,可以被子类中自己定义的任何实例方法调用;

 也就是说,如果子类中定义的实例方法不能操作父类的某个成员变量或方法,那么该成员变量或方法就没有被子类继承。

(3)子类和父类在同一个包中的继承性

继承父类中不是private的成员变量或方法作为自己的成员变量或方法(继承protected、public、友好的变量及方法);继承的成员变量和方法的访问权限保持不变;

(4)子类和父类不在同一个包中的继承性

子类继承父类的protected、public成员变量或方法;继承的成员变量和方法的访问权限保持不变;

子类不能继承父类的友好变量和友好方法。

public class People {int age;String country;String sex;protected String workType;private String idcard;People(){System.out.println("调用People类的无参构造函数!");}
}class Worker extends People{	String position;public static void main(String[] args) {Worker one = new Worker();one.age = 10;one.country = "China";one.workType = "worker";//one.idcard = "123456";		//×,在同一个包中,不继承private变量	}
}
package eight;
public class People1 {int age;String country;public String sex;protected String workType;private String idcard;public People1(){System.out.println("调用People类的无参构造函数!");}
}package object.oriented;
import eight.People1;class Teacher extends People1{public static void main(String[] args) {Teacher two = new Teacher();two.sex = "male";   //√,子类继承父类的public成员变量//two.age = 10;		//×,不在同一个包中时,不继承友好变量two.workType = "student";    //√,不在同一个包中时,可继承protected变量}
}

注意:

无论是否在一个包中,均可继承protected、public变量及方法;

只有在同一个包中,子类才可继承友好变量及友好方法;

3、子类对象的构造过程

构造过程:用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,也就是说,如果子类的构造方法中没有明显地指明使用父类的哪个构造方法,子类就调用父类中不带参数的构造方法。(super关键字)

子类对象的特点:

(1)用子类创建对象时,不仅子类中声明的成员变量被分配了内存

(2)父类的成员变量也都分配了内存空间,但只将其中一部分(子类继承的那部分)作为分配给子类对象的变量。

(3)子类中还有一部分方法是从父类继承的,这部分方法却可以操作这部分未继承的变量。

4、成员变量的隐藏和方法重写 

 成员变量的隐藏

对于子类可以从父类继承的成员变量,只要子类中声明的成员变量和父类中的成员变量同名时,子类就隐藏了继承的成员变量;

需要注意:子类对象可以调用从父类继承的方法操作隐藏的成员变量

package object.oriented;class People1 {public double x; // 父类的double类型成员变量xpublic void setX(double x) {this.x = x; // 设置父类的x}public double getDoubleX() {return x; // 返回父类的double x}
}class Student1 extends People1 {int x; // 子类定义int类型x,隐藏父类的double xpublic int getX() {return x; // 返回子类的int x}
}public class Example5_3 {public static void main(String args[]) {Student1 stu = new Student1();stu.x = 98; // 合法:操作子类的int xSystem.out.println("对象stu的x的值是:" + stu.getX()); // 输出98// stu.x = 98.98; // 非法:子类x是int,不能赋double值stu.setX(98.98); // 合法:调用父类的setX方法,设置父类的double xSystem.out.println("父类的x的值是:" + stu.getDoubleX()); // 输出98.98System.out.println("子类的x的值是:" + stu.x); // 输出98(未被修改)}
}

方法重写

子类通过重写可以隐藏已继承的实例方法(方法重写也被称为方法覆盖)。如果子类可以继承父类的某个实例方法,那么子类就有权利重写这个方法;

重写:子类中定义一个方法,这个方法的类型和父类方法的类型一致,或父类的方法类型的子类型,且方法名、参数个数、参数类型和父类的方法完全相同。

(子类型是指:如果父类的方法类型是“类”,那么允许子类的重写方法类型是“子类”)

重写方法既可以操作继承的成员变量,也可以操作子类新声明的成员变量。(不能操作隐藏的成员变量)

重写父类的方法时,不可以降低方法的访问权限。

class AA{double f(float x,float y) {return x+y;}public int g(int x,int y) {return x+y;}
}class BB extends AA{double f(float x,float y) {return x*y;}
}public class Example5_4 {public static void main(String[] args) {BB b = new BB();double result = b.f(5, 6);	//b调用重写的方法System.out.println("调用重写方法得到的结果:"+ result);int m = b.g(3, 5);System.out.println("调用继承方法得到的结果:"+ m);}
}

 5、super关键字

(1)在子类中,想使用被子类隐藏的成员变量或方法就可以使用super关键字。

// 定义Animal类
class Animals {		String name = "牧羊犬";//定义动物叫的方法		void shout() {			  System.out.println("动物发出叫声");}
}// 定义Dog类继承动物类
class Dogs extends Animals {    //重写父类Animal中的shout()方法,扩大了访问权限public void shout() {			 super.shout();      //调用父类中的shout()方法System.out.println("汪汪汪……");  }public void printName(){//调用父类中的name属性System.out.println("名字:"+super.name);          }
}public class Example05 {public static void main(String[] args) {Dogs dog = new Dogs();  // 创建Dog类的实例对象dog.shout();            // 调用dog重写的shout()方法dog.printName();        // 调用Dog类中的printName()方法}}

(2)使用super调用父类的构造方法

子类不继承父类的构造方法;

子类如果想使用父类的构造方法,必须在子类的构造方法中使用,并且必须使用super关键字来表示,而且super必须是子类构造方法的第一条语句。

public class Student {int number;String name;Student(){}Student(int number,String name){this.number=number;this.name=name;}public int getNumber() {return number;}public String getName() {return name;}
}public class UniverStudent extends Student{boolean isMarriage;UniverStudent(int number,String name,boolean b){super(number,name);		//调用父类的构造方法}public boolean getIsMarriage() {return isMarriage;}
}

(3)使用super操作被隐藏的成员变量和方法

子类想使用被子类隐藏的成员变量或方法,就可以使用super关键字。

当super调用隐藏的方法时,该方法中出现的成员变量是指被隐藏的成员变量。

6、final关键字

final的英文意思是“最终”。在Java中,可以使用final关键字声明类、属性、方法,在声明时需要注意以下几点:

(1)使用final修饰的类不能有子类,即不能被继承。

(2)使用final修饰的方法不能被子类重写。

(3)使用final修饰的变量(成员变量和局部变量)是常量,常量不可修改。

Java中的类被final关键字修饰后,该类将不可以被继承,即不能够派生子类。

// 使用final关键字修饰Animal类
final class Animal {
}
// Dog类继承Animal类
//class Dog extends Animal //类被final关键字修饰后,该类将不可以被继承
//{
//}public class Example07 {public static void main(String[] args) {}
}

当一个类的方法被final关键字修饰后,这个类的子类将不能重写该方法。

Java中被final修饰的变量是为常量,常量只能在声明时被赋值一次,在后面的程序中,其值不能被改变。如果再次对该常量赋值,则程序会在编译时报错。

在使用final声明变量时,要求全部的字母大写。如果一个程序中的变量使用public static final声明,则此变量将成为全局变量,如下面代码所示。 public static final String NAME = "哈士奇";

 public class Example09 {public static void main(String[] args) {final int AGE = 18;    // 第一次可以赋值AGE = 20;               // 再次赋值会报错}}

7、对象的上转型对象

假设,A类是B类的父类,当用子类创建一个对象,并把这个对象的引用放到父类的对象中时,比如:

A  a;
a = new B();
//或
A a;
B  b = new B();
a = b;
//这时,称对象a是对象b的上转型对象。
class Animal {
}public class Tiger extends Animal{public static void main(String[] args) {Animal a;Tiger b = new Tiger();a = b;}
}

对象的上转型的实体是由子类负责创建的,但上转型对象会失去源对象的一些属性和功能。

(1)上转型对象不能操作子类新增的成员变量(失掉了这部分属性),不能调用子类新增的方法(失掉了一些功能)

(2)上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类的重写方法。

上转型对象操作子类继承的方法或子类重写的方法,其作用等价于子类对象去调用这些方法。

因此,如果子类重写了父类的某个方法后,当对象的上转型对象调用这个方法时一定是调用了子类重写的方法。

class Anthropoid {double m = 12.58;void crySpeak(String s) {System.out.println(s);}}class People extends Anthropoid{char m = 'A';int n = 60;void computer(int a,int b) {int c = a+b;System.out.println("a+b的和为"+c);}void crySpeak(String s) {System.out.println(m+"**"+s+"**"+m);}}public class Example5_9{public static void main(String args[]) {People person = new People();Anthropoid monkey = person;		//monkey是person对象的上转型对象monkey.crySpeak("I love this game"); 	//等同于person调用重写的crySpeak方法//monkey.n = 100;		//非法,因为n是子类新增的成员变量//monkey.computer(12,19);	//非法,因为computer()是子类新增的方法System.out.println(monkey.m); 	//操作隐藏的m,不等同于person.mSystem.out.println(person.m); 	//操作子类的mPeople zhang = (People)monkey;	//将上转型对象强制转化为子类的对象zhang.computer(55, 33); 		//zhang是子类的对象zhang.m = 'T';System.out.println(zhang.m);}
}

相关文章:

  • PyTorch DDP 跨节点通信的底层机制
  • C++学习之游戏服务器开发十四QT登录器实现
  • 文献×汽车 | 基于 ANSYS 的多级抛物线板簧系统分析
  • 什么事Nginx,及使用Nginx部署vue项目(非服务器Nginx压缩包版)
  • 边缘计算全透视:架构、应用与未来图景
  • 区间分组详解
  • 83k Star!n8n 让 AI 驱动的工作流自动化触手可及
  • 使用Spark-TTS-0.5B模型,文本合成语音
  • Lua 第7部分 输入输出
  • React.cloneElement的用法详解
  • Flowable 与 bpmn.io@7.0 完整集成示例 Demo
  • 解决IntelliJ IDEA配置文件(application.properties)中文注释变成乱码的问题
  • 明远智睿2351开发板:四核1.4G处理器——开启高效能Linux系统新纪元
  • 耀百岁中医养生与上海隽生中医药研究中心达成战略合作——共筑中医养生科研创新高地
  • 【JavaEE】-- MyBatis操作数据库(1)
  • spring中使用netty-socketio部署到服务器(SSL、nginx转发)
  • STM32F103C8T6 HAL库 U盘模式(MSC)
  • Pycharm(十五)面向对象程序设计基础
  • Linux 内核中 cgroup 子系统 cpuset 是什么?
  • 【专题刷题】滑动窗口(三)
  • 事故调查报告:东莞一大楼装修项目去年致1人死亡,系违规带电作业
  • 安且吉兮,西泠印社雅集吴昌硕故里
  • 浙江一季度GDP为22300亿元,同比增长6.0%
  • 尹锡悦涉嫌发动内乱案第二次庭审举行
  • 平均25岁,天津茱莉亚管弦乐团进京上演青春版《春之祭》
  • 特朗普亲自介入美日关税谈判:以势压人还是给对手“送助攻”