Java基础复习(DaySix,java基础入门课后答案文库

Java基础复习(DaySix,java基础入门课后答案文库,第1张

Java基础复习(DaySix,java基础入门课后答案文库

}

@Override

public String getName() {

return name;

}

@Override

public void setName(String name) {

this.name = name;

}

@Override

public Integer getId() {

return id;

}

@Override

public void setId(Integer id) {

this.id = id;

}

@Override

public String getNick() {

return nick;

}

@Override

public void setNick(String nick) {

this.nick = nick;

}

}

下面是父类

public class FatherTwo {

private Integer age;

private String name;

public String nick;

public Integer id;

public FatherTwo(Integer age, String name, String nick, Integer id) {

this.age = age;

this.name = name;

this.nick = nick;

this.id = id;

}

public FatherTwo() {

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getNick() {

return nick;

}

public void setNick(String nick) {

this.nick = nick;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

}

调用方法测试一下方法与属性的优先级

public class TestExtend {

public static void main(String[] args) {

FatherTwo father = new SonTwo(1,“我是son”,1,“son”);

//方法是优先访问子类

System.out.println(father.getName());

System.out.println(father.getNick());

System.out.println(father.getId());

System.out.println(father.getAge());

//可以看到,会优先访问父类

System.out.println(father.id);

System.out.println(father.nick);

}

}

可以看到,没有子类的getOld方法,证明不可以调用父类没有的方法

阻止继承:final类和方法


给类加上final关键字,那么该类就不会被继承

给类中的特定方法加上final关键字,那么该方法就不可以被子类覆盖重写,final类中的所有方法自动地变成final方法

给属性加上final关键字,那么该属性必须在类构建实例的时候进行初始化,而且构建实例之后,这个属性不可以再被修改。

强制类型转化


前面已经学习过基本数据类型进行强制转换。

那么对于引用类型进行强制转化会怎样

将一个值赋值给变量时,编译器会去检查这样的行为是否承诺过多,如果将一个子类的引用赋值给父类的变量,那就没问题,如果将一个父类的变量引用赋值给子类,那么就承诺过多了(父类没有子类的完全功能,这个变量会缺少一部份功能),必须要进行强制转换。

应用类型的强制转化有如下规则

  • 只能在继承层次内进行强制转换

  • 在将父类强制转换成子类之前,应该使用instanceof进行检查

  • instanceof会查看是否能够成功地转化,如果可以,那就返回True,如果不行,就会返回false

我们仍然使用上面的父与子类来测试

public class TestExtend {

public static void main(String[] args) {

FatherTwo father = new SonTwo(1,“我是son”,1,“son”);

FatherTwo fatherTwo = new FatherTwo();

System.out.println(father instanceof SonTwo);

System.out.println(fatherTwo instanceof SonTwo);

}

}

可以看到,若父引用要可以强转成子变量,前提是这个父引用是子引用来的。

抽象类


继承产生了一种自上而下的层次结构,最上面的类更加具有一般性,可能更加抽象,而下层的类则在不断扩展

祖先类更有一般性,人们只将它作为派生其他类的基类,而不会去用来实例化想要得到的对象

抽象类的规则如下

  • 抽象类可以有抽象方法,其他属性和方法都跟一般类一致(可以有public、protected和default这些修饰符)

  • 抽象类不可以去实例化

  • 抽象类也可以有自己的静态变量和静态方法,同样也可以直接使用抽象类进行调用

  • 继承抽象类的所有对象也会继承静态方法和静态变量

  • 如果抽象类被继承(只能被单继承)

  • 如果是抽象类继承抽象类,可以不去实现父抽象类的抽象方法(但该抽象方法也会被子抽象类继承下来)

  • 如果是一般类继承抽象类,必须去实现父抽象类的抽象方法

  • 继承类无论是抽象类还是子类,都要在构造方法上调用super来构造父抽象类的实例

  • 抽象类也要有自己的构造方法,只可以被子类使用super来调用(因为属性还是位于抽象类里面,需要对外提供构造方法来进行实例化),在单元测试上是不可以调用的,也就是不支持使用new去实例

权限修饰符


  1. 对外部完全可见——public

  2. 对本包和所有子类可见——protected

  3. 对本包可见——默认,不需要修饰符

  4. 仅仅对本类可见——private

一般来说,想要进行限制某个方法或者变量的话,使用protected。

Object:所有类的超类


Object类是Java中所有类的始祖,每个类都扩展了Object,但是并不需要去手动继承

如果没有明确指出超类,Object就被认为是这个类的超类

可能这里有人以为,那明确指出超类,不就没有Object当父类了吗?

其实并不是这样,因为Object始终位于架构的最上层,也就是最模糊最抽象的一层。

Object的equals方法

可以看到Object实例的equals方法仅仅用于检测一个对象是否等于另外一个对象,即判断两个对象的引用地址是否相等

但Oject还提供了静态的比较方法

可以看到静态方法的equals不仅检测两个对象的引用地址是否相等,还会去检测一方是否为空,如果不为空,调用这一方的equals方法,前面提到过,如果Object a是由多态而来的,equals方法会优先调用子类的重写,所以这里不一定会调用object实例的equals

但一般这种机制不太够用,所以有时候类也要去重写equals方法。

public class Employee {

private String nickName;

private Integer employId;

public Employee(String nickName, Integer employId) {

this.nickName = nickName;

this.employId = employId;

}

public Employee() {

}

/idea自动生成的重写方法/

@Override

public boolean equals(Object o) {

//先判断是否是同一个引用

if (this == o) {return true;}

//判断比较的对象是否为空

//getClass方法是获取一个实例对象所属的类

//判断是不是通一个类

if (o == null || getClass() != o.getClass()){ return false;}

//强转成同一个类

Employee employee = (Employee) o;

//比较两个类的属性是否一样

//这里使用equals进行比较,注意这里的是静态方法equals

//也就是,如果属性如果为引用

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

类型,那么就会优先调用该引用类型重写的equals方法

return Objects.equals(nickName, employee.nickName) &&

Objects.equals(employId, employee.employId);

}

@Override

public int hashCode() {

return Objects.hash(nickName, employId);

}

}

可以看到,除了比较应用地址和类的类型之外,还会进行比较值,比较值的过程如下

  • 调用Object的静态equals方法

  • 会先比较属性的引用地址

  • 然后比较其中一方是否为null,如果为null,就返回false

  • 如果其中一方不为null,就会调用这一方的equals方法进行比较

  • 继承关系会优先调用子类的equals方法

相等测试与继承

对于equals方法,可以看到只要class不一样,就会返回false,那么可能有一些人就想子类也能与父类进行比较

那么可以将类判断改成如下

//假设Employee是一个超类,Manager是一个子类

if(!(otherObject instanceof Employee)){return false;}

那么Employ实例的equals方法也可以跟Manager进行属性比较了

但强烈建议这种方式不太好

Java语言规范要求equals方法要有下面的特性

  • 自反性:对于任何非空引用x,x.equals(x)应该返回true

  • 对称性:对于任何引用x和y,x.equals(y)返回True时,那么y.equals(x)也要返回True

  • 传递性:对于任何引用x、y和z,x.equals(z)返回True,y.equals(z)返回True,那么x.equals(y)也要返回True

假如使用了上面的判断

employee.equal(manager) //这是可以的,因为Manager instance Employee为true

manager.equal(employee) //这是不可以的,因为Employee instance Manager为false(承诺过多)

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5660263.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存