题九
- 定义父类Point 类,包含x 和y 坐标两个属性
- 定义子类LabeledPoint 类,包含label 属性
- 创建子类对象并输出其内容
package com.test;
public class Point {
private int x;
private int y;
public Point() {
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
package com.test;
public class LabeledPoint extends Point {
private String label;
public LabeledPoint() {
}
// 子类继承父类的成员,先通过父类构造器初始化父类成员,再通过子类构造器初始化子类成员
public LabeledPoint(String label, int x, int y) {
super(x, y);
this.label = label;
}
@Override
public String toString() {
return "LabeledPoint{" +
"label='" + label + '\'' +
", (" + getX() + ", " + getY() + ")" +
'}';
}
public static void main(String[] args) {
LabeledPoint p = new LabeledPoint("test", 1, 2);
// LabeledPoint{label = 'test', (1, 2)}
System.out.println(p);
}
}
题十
- 编写Doctor 类,包含name- 名字、age- 年龄、job- 工作、gender- 性别、sal- 工资五个属性
- 重写equals 方法
- 创建两个Doctor 对象,并通过equals 判断两个对象是否相同(标准为内容是否相同)
package com.test;
import java.util.Objects;
public class Doctor {
private String name;
private int age;
private String jobName;
private char gender;
private String salary;
public Doctor() {
}
public Doctor(String name, String jobName, int age, char gender, String salary) {
this.name = name;
this.jobName = jobName;
this.age = age;
this.gender = gender;
this.salary = salary;
}
@Override
public boolean equals(Object o) {
// 如果地址相同,则说明为同一个对象
if (this == o) return true;
// 如果对象为空或者类型不同,则说明不相同(直接调用getClass() 等同于this.getClass())
if (o == null || getClass() != o.getClass()) return false;
// 转换为 Doctor 类型,并判断内容是否相同
Doctor doctor = (Doctor) o;
return age == doctor.age
&& gender == doctor.gender
&& Objects.equals(name, doctor.name)
&& Objects.equals(jobName, doctor.jobName)
&& Objects.equals(salary, doctor.salary);
}
/**
* 为了满足一致性要求,需要重写 hashCode 方法
* 即两个对象equals 结果为true,则应该产生相同的哈希码
* @return hashCode
*/
@Override
public int hashCode() {
return Objects.hash(name, age, jobName, gender, salary);
}
public static void main(String[] args) {
Doctor doctor1 = new Doctor("张三", "医生", 30, '男', "10000");
Doctor doctor2 = new Doctor("张三", "医生", 30, '男', "10000");
// true
System.out.println(doctor1.equals(doctor2));
}
}
题十一
- 定义父类Person 类,包含run 和eat 两个方法
- 定义子类Student 类,重写run,并新增study 方法
- 判断在向上和向下转型时,分别可以调用哪些方法?输出了什么?
package com.test;
class Person {
public void run() {
System.out.println("Person is running");
}
public void eat() {
System.out.println("Person is eating");
}
}
public class Student extends Person {
@Override
public void run() {
System.out.println("Student is running");
}
public void study() {
System.out.println("Student is studying");
}
public static void main(String[] args) {
Person person = new Student();
// Person is eating -> 运行类型为 Student,但子类没有重写eat 方法
person.eat();
// Student is running -> 运行类型为 Student,且子类中重写了run 方法
person.run();
Student student = (Student) person;
// Student is running
student.run();
// Student is studying -> 运行类型为 Student,且子类中具有study 方法
student.study();
// Person is eating
student.eat();
}
}
题十二
- 说出 == 和equals 的区别
两者都用于比较,区别如下:
- 类型:== 是比较运算符,equals 是Object 类中的方法
- 操作:== 用于比较值是否相等,equals 底层使用 == 进行比较
- 实际:对于引用类型,== 和equals 只能判断是否为同一个对象。所以通常会在子类中重写equals 方法,实现内容比较
题十三
- 定义Student 类,包含name- 名字、age- 年龄,sex- 性别和id- 学号四个属性
- 定义Teacher 类,包含name- 名字、age- 年龄,sex- 性别和workTime- 工龄四个属性
- Student 类中新增study 方法,Teacher 类中新增teach 方法
- 向上抽取一个共同的父类Person,新增play 方法
- Student 和Teacher 对于play 方法有不同的实现,分别为打游戏和打太极
- 测试类中定义数组,存放Student 和Teacher 各两个对象,并按照年龄从低到高排序
- 打印对象信息,并调用对应study 和teach 方法
package com.test;
public class Student extends Person {
private String id;
public Student() {
}
public Student(String name, int age, String sex, String id) {
super(name, age, sex);
this.id = id;
}
public String getId() {
return id;
}
/**
* 打印学生信息
*/
public void printInfo() {
System.out.println("student info: \n\tname: " + getName() +
"\n\tage:" + getAge() +
"\n\tsex: " + getSex() +
"\n\tid: " + id);
}
public void study() {
System.out.println("student study ...");
}
@Override
public void play() {
System.out.println("student play game ...");
}
}
package com.test;
public class Teacher extends Person {
private int workTime;
public Teacher() {
}
public Teacher(String name, int age, String sex, int workTime) {
super(name, age, sex);
this.workTime = workTime;
}
public int getWorkTime() {
return workTime;
}
public void printInfo() {
System.out.println("teacher info:\n\tname: " + getName() +
"\n\tage: " + getAge() +
"\n\tsex: " + getSex() +
"\n\tworkTime: " + workTime);
}
public void teach() {
System.out.println("teacher teach ...");
}
@Override
public void play() {
System.out.println("teacher doTaiChi ...");
}
}
package com.test;
public class Person {
private String name;
private int age;
private String sex;
public Person() {
}
public Person(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
public void play() {
System.out.println("person play...");
}
}
package com.test;
public class Test {
public static void main(String[] args) {
Person[] persons = new Person[4];
persons[0] = new Student("张三", 18, "男", "2019001");
persons[1] = new Teacher("李四", 30, "男", 20);
persons[2] = new Student("王五", 19, "男", "2019002");
persons[3] = new Teacher("赵六", 35, "男", 25);
Test test = new Test();
test.sort(persons);
for (int i = 0; i < persons.length; i++) {
test.print(persons[i]);
}
}
public void print(Person persons) {
if (persons instanceof Student) {
Student student =(Student) persons;
student.printInfo();
student.study();
} else {
Teacher teacher =(Teacher) persons;
teacher.printInfo();
teacher.teach();
}
System.out.println("--------------------------------");
}
public void sort(Person[] persons) {
for (int i = 0; i < persons.length - 1; i++) {
for (int j = 0; j < persons.length - 1 - i; j++) {
if (persons[j].getAge() > persons[j + 1].getAge()) {
Person temp = persons[j];
persons[j] = persons[j + 1];
persons[j + 1] = temp;
}
}
}
}
}
题十四
- 判断以下代码执行结果
package com.test;
class A {
public A() {
System.out.println("A 的无参构造...");
}
}
class B extends A {
public B() {
System.out.println("B 的无参构造...");
}
public B(String name) {
System.out.println("B 的有参构造...");
}
}
class C extends B {
public C() {
System.out.println("C 的无参构造...");
}
public C(String name) {
super("张佳乐");
System.out.println("C 的有参构造...");
}
}
public class Test {
public static void main(String[] args) {
// A 的无参构造...
// B 的无参构造...
// C 的无参构造...
C c = new C();
}
}
题十五
- 什么是多态?
- 多态的具体体现有哪些?
多态是面向对象编程的一个核心特性,它允许子类可以被当作其父类对象来使用。多态的本质就是父类引用可以指向多种子类对象,具备不同的具体实现,从而使得程序更具灵活性和可扩展性。
多态体现在静态多态(早期绑定或编译时多态)和动态多态(后期绑定或运行时绑定)
- 静态多态通常指OverLoad - 方法重载,即在一个类中可以存在多个方法名相同但参数列表不同的方法。编译器根据传递的参数类型来确定调用哪个方法版本,这种多态是在编译期确定的
- 动态多态通常指Override - 方法重写,即子类可以重新定义父类中的方法。当父类引用指向子类对象时,通过该引用调用的实际方法是子类中定义的方法,这种多态是在运行期确定的
题十六
- 什么是动态绑定机制
动态绑定也被称为后期绑定或运行时绑定,是指程序在执行期间根据对象的实际类型来确定调用哪个方法的机制。在编译时,编译器只知道方法调用的形式,并不知道具体调用的方法体,只有在运行阶段,JVM 才会根据对象的类型确定具体调用哪个方法。
Java 当中每个类都有一个虚方法表,其中包含了类中所有方法的指针。当创建一个对象时,这个对象就会有一个指向其类虚方法表的指针。当调用一个方法时,JVM 会通过该指针找到对应的方法实现。此时即便子类重写了父类中的方法,也会调用子类中重写的方法实现。