上次我为大家写出啦“继承性”,继承性是面向对象三大特性之一是Java学习必备的知识,如没有了解透彻的话请打开下方文章在进行观看一下哦!!今天我们在来说一下继承性必须要掌握的知识点,主要内容有以下几点:
- Object类
- 继承情况下构造方法的调用过程
- super关键字
- ==和equals方法
- 组合
需要这些知识点的同学我们来开始学习。
学习教程推荐:
- 1.北京高淇Java300集(Java强烈推荐)
Java300集零基础适合初学者视频教程_Java300集零基础教程_Java初学入门视频基础巩固教程_Java语言入门到精通 - 2.JavaSE基础全套-从零开始进阶之大神(推荐)
系统教学JavaSE基础全套课程-从0开始进阶至大神_线下录制Java系列课程Java从入门到精通_/JAVA基础/数组/OOP/集合/IO流_ - 3.Java常用类基础实战
【基础夯实】Java常用类实战基础教程_Java八大常用类核心基础_Java常用类基础入门/Java包装类/String类 - 4.Java基础入门必备数学知识【数据结构与算法】(推荐)
Java基础入门必学知识数据结构与算法_Java数据结构与算法基础到进阶/Java基础入门进阶/Java数据结构分析/Java数据结构常见问题_哔哩哔哩_bilibili - 5.Java面向对象编程_OOP基础深入讲解
Java面向对象编程重基础深入讲解_OOP面向对象Java基础干货分享/JavaSE/面向对象编程/OOP程序设计 - 6.GOF23种设计模式-23中设计模式详解课程
GOF23种设计模式讲解_Java gof23种设计模式详解课程_从单例到备忘录模式 23种模式详解
1、Object类
Object类是所有Java类的根基类,也就意味着所有的Java对象都拥有Object类的属性和方法。如果在类的声明中未使用extends关键字指明其父类,则默认继承Object类。
Object类的方法摘要:
以上方法是Object类的所有方法吗?不是是Object类所有的public方法。 除此之外可能还有private、protected、默认的方法
2、成员变量的隐藏
如果父类和子类中有同名的成员变量,不存在变量的重写,分别占有自己的空间。子类的成员变量优先,称为:成员变量的隐藏。
如下示例代码:
public class Animal {
String color="Animal的color";
int age;
public String getColor(){
return color;
}
}
public class Dog extends Animal {
String color ="Dog的color";
String nickName;
public String getColor(){
return color;
}
public String getSuperColor(){
return super.getColor();
}
public void show(){
String color = "方法的color";
System.out.println(color);
System.out.println(this.color);
System.out.println(super.color);
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.show();
System.out.println(dog.getColor());
System.out.println(dog.getSuperColor());
}
}
3、继承情况下构造方法的调用过程
继承条件下构造方法的执行顺序:
- 构造方法的第一条语句默认是super(),含义是调用父类无参数的构造方法
- 构造方法的第一条语句可以显式的指定为父类的有参数构造方法:super(.....)
- 构造方法的第一条语句可以显式的指定为当前类的构造方法:this(.....)
注意事项:
- 每个类最好要提供无参数的构造方法
- 构造方法的第一条语句可以是通过super或者this调用构造方法,须是第一条语句
- 构造方法中不能同时使用super和this调用构造方法,并不是说不能同时出现this和super
代码示例:继承情况下构造方法的调用过程
public class Animal {
String color;
private int age;
public Animal(){
super();
}
public Animal(String color,int age){
this.color = color;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Dog extends Animal {
private String nickName;
private String type;
public Dog(){
super();
}
public Dog(String color,int age,String nickName){
//super();
super(color,age);
//this(color,age,nickName,"aaa");
this.nickName = nickName;
}
public Dog(String color,int age,String nickName,String type){
//super();
//super(color,age);
this(color,age,nickName);
//this.nickName = nickName;
this.type = type;
}
public String toString() {
return this.color+" "+ this.getAge()+" "+this.nickName+" "+this.type;
}
public static void main(String[] args) {
Dog dog = new Dog("黑色",3,"旺财","泰迪");
System.out.println(dog.toString());
}
}
4、super关键字
前面的示例中已经多次使用到了super关键字。
super“可以看做”是直接父类对象的引用。每一个子类对象都会有一个super引用指向其直接父类对象。
使用super可以
1) 调用成员变量 super.color
2) 调用成员方法 super.introduce();
3) 调用构造方法 super(color,age);
注意
1) 使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。
2) 在一个类中,若是构造方法的第一行代码没有显式的调用super(...)或者this(...);那么Java默认都会调用super(),含义是调用父类的无参数构造方法。这里的super()可以省略。
5、==和equals方法
“==”代表比较双方是否相同。如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。
Object类中定义有:public boolean equals(Object obj)方法,提供定义“对象内容相等”的逻辑。比如,判断两个Dog是否是一个Dog,要求color、age、nickName等所有属性都相同。
Object 的 equals 方法默认就是比较两个对象的hashcode,是同一个对象的引用时返回 true 否则返回 false。显然,这无法满足子类的要求,可根据要求重写equals方法。
代码示例:重写equals方法
public class Animal {
String color;
private int age;
public boolean equals(Object obj) {
Animal other = (Animal) obj;
//如果参数是null、,直接返回false
if(obj == null){
return false;
}
//如果两个变量指向同一个空间,直接返回true
if(this == obj ){
return true;
}
if(this.color.equals(other.color) && this.age == other.age){
return true;
}else{
return false;
}
}
}
public class Dog extends Animal {
private String nickName;
private String type;
public boolean equals(Object obj) {
Dog other = (Dog) obj;
boolean flag = super.equals(obj);
if (!flag) {
return false;
} else {
//如果Animal的equals返回true,需要再比较nickName、type
if (this.nickName.equals(other.nickName)
&& this.type.equals(other.type)) {
return true;
} else {
return false;
}
}
}
}
6、组合
继承和组合是复用代码的两种方式;
- 继承: is-a Dog is-a Animal Cat is-a Animal
- 组合: has-a Computer has-a cpu memery mainBoard。
面向对象的设计原则之一:组合聚合复用原则(优先使用组合,而不是继承)
- 除非两个类之间是“is-a”的关系,否则不要轻易的使用继承,不要单纯的为了实现代码的重用而使用继承,因为过多的使用继承会破坏代码的可维护性,当父类被修改时,会影响到所有继承自它的子类,从而增加程序的维护难度和成本。
- 不要仅仅为了实现多态而使用继承,如果类之间没有“is-a”的关系,可以通过实现接口与组合的方式来达到相同的目的。设计模式中的策略模式可以很好的说明这一点,采用接口与组合的方式比采用继承的方式具有更好的可扩展性
根据以上知识点,编写代码进行总结:
1.定义一个CPU类及其子类
public class Cpu {
private String name;//intel amd
private double rate;//速度 频率
public void calc(){
System.out.println("cpu calc......");
}
public void ctrl(){//control
System.out.println("cpu control...");
}
}
public class AMDCpu extends Cpu {
public void calc() {
System.out.println("AMD calc");
}
}
public class IntelCpu extends Cpu {
public void calc() {
System.out.println("IntelCpu calc");
}
}
2.定义MailBoard 类和Memory 类
public class MailBoard {
public void connect(){
System.out.println(" mainBoard connecting .....");
}
}
public class Memory {
public void process(){
System.out.println("memory process.....");
}
}
3.使用组合定义Computer类
public class Computer{
private Cpu cpu = new Cpu();
private Memory memory = new Memory();
private MailBoard mailBoard = new MailBoard();
private void setCpu(Cpu cpu){
this.cpu = cpu;
}
public void computer(){
cpu.calc();
cpu.ctrl();
memory.process();
mailBoard.connect();
}
public static void main(String[] args) {
Computer computer = new Computer();
//computer.setCpu(new IntelCpu());
Cpu cpu = new AMDCpu();
Cpu cpu2 = new IntelCpu();
Cpu cpu3 = new Cpu();
computer.setCpu(cpu);
computer.computer();
}
}