342-360面向对象初级作业

一、面向对象初级作业

package com.alice.homework01;
/*
    第一题:
        定义一个Person类{name, age, job},初始化Person对象数组,有三个person对象,
        并按照age从大到小进行排序,提示,使用冒泡排序。
    第二题:
        写出四种访问修饰符和各自的访问权限
                    本类  同包  子类  不同包
        public      1    1     1     1
        protected   1     1     1    0
        默认         1     1     0    0
        private      1     0    0    0
 */


public class Homework01 {
    public static void main(String[] args) {
        Person[] peopleArr = new Person[3];
        peopleArr[0] = new Person("alice", 22, "Java工程师");
        peopleArr[1] = new Person("king", 20, "Python工程师");
        peopleArr[2] = new Person("eric", 30, "嵌入式工程师");
        System.out.println("原数组如下:");
        printPersonArr(peopleArr);
        BubbleSort bubbleSort = new BubbleSort();
        bubbleSort.sort(peopleArr);
        System.out.println("排序后的数组:");
        printPersonArr(peopleArr);
    }

    public static void printPersonArr(Person[] peopleArr) {
        for (int i = 0; i < peopleArr.length; i++) {
            // System.out.println(peopleArr[i].toString());
            // 这里忘记可以直接输出了,直接输出默认调用的是toString方法,这个地方和老韩不一样
            System.out.println(peopleArr[i]);
        }
    }
}

class Person {
    private String name;
    private int age;
    private String job;

    public Person(String name, int age, String job) {
        this.name = name;
        this.age = age;
        this.job = job;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", job='" + job + '\'' +
                '}';
    }
}

class BubbleSort {
    public void sort(Person[] personArr) {
        // 这里老韩将临时变量写在外面
        // Person tmp = null;
        // 这里我推荐写在里面,变量作用域应该最小化
        // 现代 JVM 优化能力强,局部变量的创建和销毁开销极小
        // 可读性更好,变量定义在需要的地方,便于维护
        // 一些极端的场景考虑性能可能写到外面比较好。
        for (int i = 0; i < personArr.length - 1; i++) {
            for (int j = 0; j < personArr.length - i - 1; j++) {
                if (personArr[j].getAge() < personArr[j + 1].getAge()) {
                    // 这个地方结合冒泡排序可以根据任何需求进行处理
                    // 比如名字的长度排序,length()
                    Person temp = personArr[j];
                    personArr[j] = personArr[j + 1];
                    personArr[j + 1] = temp;
                }
            }
        }
    }
}

// 02
package com.alice.homework01;

/*
    第三题
        编写老师类
        1)要求有属性"name","age","post"职称,"salary"
        2)编写业务方法,introduce()实现输出一个教师信息
        3)编写教师类的三个子类:
            教授类Professor,副教授类AssociateProfessor,讲师类Lecturer。
            工资级别分别是:教授1.3,副教授1.2,讲师1.1
            在三个子类中都重写父类的introduce方法
        4)定义并初始化一个老师对象,调用业务方法,实现对象基本信息的后台打印
 */
public class Homework02 {
    public static void main(String[] args) {
        new AssociateProfessor("冯", 36, "校聘副教授", 20055.53).introduce();
    }
}

class Teacher {
    private String name;
    private int age;
    private String post;
    private double salary;
    // 这里老韩直接将共有的级别提取到这里面了

    public Teacher(String name, int age, String post, double salary) {
        this.name = name;
        this.age = age;
        this.post = post;
        this.salary = salary;
    }

    public Teacher() {
    }

    public void introduce() {
        System.out.println("姓名:" + name + "\n年龄:" + age + "\n职称:" + post + "\n工资" + salary);
        // 工资级别也输出了
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getPost() {
        return post;
    }

    public double getSalary() {
        return salary;
    }
}

/*
            教授类Professor,副教授类AssociateProfessor,讲师类Lecturer。
            工资级别分别是:教授1.3,副教授1.2,讲师1.1
            在三个子类中都重写父类的introduce方法
            方法名、参数列表(参数类型、顺序、数量)必须与父类方法完全一致。
 */
class Professor extends Teacher {
    private double salaryGrade = 1.3;

    public Professor(String name, int age, String post, double salary) {
        super(name, age, post, salary);
    }

    public void introduce() {  // 老韩这里直接super调用父类的introduce
        System.out.println("姓名:" + getName() + "\n年龄:" + getAge() + "\n职称:" +
                getPost() + "\n工资" + getSalary() * salaryGrade);
    }
}

class AssociateProfessor extends Teacher {
    private double salaryGrade = 1.2;

    public AssociateProfessor(String name, int age, String post, double salary) {
        super(name, age, post, salary);
    }

    public void introduce() {
        System.out.println("姓名:" + getName() + "\n年龄:" + getAge() + "\n职称:" +
                getPost() + "\n工资" + getSalary() * salaryGrade);
    }
}

class Lecturer extends Teacher {
    private double salaryGrade = 1.1;

    public Lecturer(String name, int age, String post, double salary) {
        super(name, age, post, salary);
    }

    public void introduce() {
        System.out.println("姓名:" + getName() + "\n年龄:" + getAge() + "\n职称:" +
                getPost() + "\n工资" + getSalary() * salaryGrade);
    }
}

//3
package com.alice.homework01;

import java.util.Scanner;
/*
    第四题
        通过继承实现员工工资核算打印功能 1
        父类:员工类 1
        子类:部门经理类,普通员工类 1
        1)部门经理工资=1000+单日工资*天数*等级(1.2)。 1  tip,老韩分析出1000是奖金
        2)普通员工工资=单日工资*天数*等级(1.0)。 1
        3)员工属性:姓名,单日工资,工作天数。 1
        4)员工方法(打印工资) 1
        5)普通员工及部门经理都是员工子类,需要重写打印工资方法 1
        6)定义并初始化普通员工对象,调用打印工资方法输入工资,定义并初始化部门经理对象,调用打印工资方法输入工资 1

        总的来说:这道题老韩强调代码的复用,去提取属性,我这里提取的不好
 */

public class Homework03 {
    public static void main(String[] args) {
        GeneralEmployee alice = new GeneralEmployee("alice", 50, 10);
        alice.printSalary();
        Manager bob = new Manager("bob", 100, 20);
        bob.printSalary();
    }
}

class Employee {
    // 3)员工属性:姓名,单日工资,工作天数。
    private String name;
    private double dailyWage;
    private int days;
    // 两个子类还有等级,老韩又添加了一个等级,还有奖金也设置成为了属性

    public Employee(String name, double dailyWage, int days) {
        this.name = name;
        this.dailyWage = dailyWage;
        this.days = days;
    }

    // 4)员工方法(打印工资)
    public void printSalary() {
        // 2)普通员工工资=单日工资*天数*等级(1.0)。
        System.out.println("员工工资:" + (dailyWage * days * 1.0));
    }

    public String getName() {
        return name;
    }

    public double getDailyWage() {
        return dailyWage;
    }

    public int getDays() {
        return days;
    }
}

class Manager extends Employee {
    // 老韩:奖金是不确定的,可以通过set
    public Manager(String name, double dailyWage, int days) {
        super(name, dailyWage, days);
    }

    // 5)普通员工及部门经理都是员工子类,需要重写打印工资方法
    @Override
    public void printSalary() {
        System.out.println(getName() + "工资:" + (1000 + getDailyWage() * getDays() * 1.2));
    }
}

class GeneralEmployee extends Employee {

    public GeneralEmployee(String name, double dailyWage, int days) {
        super(name, dailyWage, days);
    }

    // 5)普通员工及部门经理都是员工子类,需要重写打印工资方法
    @Override
    public void printSalary() {
        System.out.println(getName() + "工资:" + (getDailyWage() * getDays() * 1.0));
    }
}


// 4
package com.alice.homework01;

import com.sun.corba.se.spi.orbutil.threadpool.Work;

/*
    第五题
        设计父类-员工类。子类:工人类Worker,农民类Peasant,教师类Teacher,科学家类Scientist,服务生类Waiter 1
        1)其中工人,农民,服务生只有基本工资 1
        2)教师除了基本工资之外,还有课酬(元/天)1 // 这里应该还隐藏一个工作天数
        3)科学家除了基本工资之外,还有年终奖1  // 这里应该还隐藏一个年终奖
        (tip:由以上的基本工资判断是一个公共的属性提取到父类中)
        4)编写一个测试类,将各种类型的员工的全年工资打印出来  // 这里应该还要提取一个公共的方法来,重写
 */
public class Homework04 {
    public static void main(String[] args) {
        Worker worker = new Worker(8000);
        worker.printAnnualSalary();
        Peasant peasant = new Peasant(3000);
        peasant.printAnnualSalary();
        TeacherFour teacherFour = new TeacherFour(6000, 365, 50);
        teacherFour.printAnnualSalary();
        Scientist scientist = new Scientist(20000, 50000);
        scientist.printAnnualSalary();
        Waiter waiter = new Waiter(3500);
        waiter.printAnnualSalary();
    }
}

// 设计父类-员工类
class EmployeeFour {  // 这里和之前该包下的类重名了故此设置为EmployeeFour,老韩采用建子包的方式
    private double baseSalary;
    // 老韩这里还添加了一个名字
    // 还分析出来一个带薪的月份,即有变化的做成一个属性,这里我直接默认12个月了,没有做成属性
    // 这个地方其实可以搞一个构造方法,子类直接super即可,这里我没搞
    public void printAnnualSalary() {
        System.out.println("全年工资->" + (baseSalary*12));
    }

    public double getBaseSalary() {
        return baseSalary;
    }

    public void setBaseSalary(double baseSalary) {
        this.baseSalary = baseSalary;
    }
}

// 工人类Worker
class Worker extends EmployeeFour {
    public Worker(double baseSalary) {
        setBaseSalary(baseSalary);
    }

    public void printAnnualSalary() {
        System.out.print("工人");
        super.printAnnualSalary();
    }
}

// 农民类Peasant
class Peasant extends EmployeeFour {
    public Peasant(double baseSalary) {
        setBaseSalary(baseSalary);
    }

    public void printAnnualSalary() {
        System.out.print("农民");
        super.printAnnualSalary();
    }
}

// 教师类Teacher
class TeacherFour extends EmployeeFour {  // 这里也和之前的重名了
    private int workDay;
    private double teachingFee;
    public TeacherFour(double baseSalary, int workDay, double teachingFee) {
        setBaseSalary(baseSalary);
        setWorkDay(workDay);
        setTeachingFee(teachingFee);
    }

    public void setWorkDay(int workDay) {
        this.workDay = workDay;
    }

    public void setTeachingFee(double teachingFee) {
        this.teachingFee = teachingFee;
    }

    public void printAnnualSalary() {
        System.out.println("教师类全年工资->" + (getBaseSalary()*12 + workDay*teachingFee));
    }
}

// 科学家类Scientist
class Scientist extends EmployeeFour {
    private double yearEndBonus;

    public Scientist(double baseSalary, double yearEndBonus) {
        setBaseSalary(baseSalary);
        setYearEndBonus(yearEndBonus);
    }

    public void setYearEndBonus(double yearEndBonus) {
        this.yearEndBonus = yearEndBonus;
    }

    public void printAnnualSalary() {
        System.out.println("科学家类全年工资->" + (getBaseSalary()*12 + yearEndBonus));
    }
}

// 服务生类Waiter
class Waiter extends EmployeeFour {
    public Waiter(double baseSalary) {
        setBaseSalary(baseSalary);
    }

    public void printAnnualSalary() {
        System.out.print("服务生");
        super.printAnnualSalary();
    }
}
/*
    第六题:
        假定Grand、Father和Son在同一个包中,问:父类和子类中通过this和super都可以调用哪些属性和方法
 */
class Grand{
    String name = "AA";
    private int age = 100;
    public void g1() {}
}
class Father extends Grand {
    String id = "001";
    private double score;
    public void f1() {
        //super可以访问哪些成员(属性和方法)?
        //super直接访问父类Grand,Grand中有一个private的不能访问,
        //name和g1均可访问

        //this可以访问哪些成员?
        //this先找本类,id可以访问,score可以访问,f1可以访问,因为在本类
        //name在Father中没有,但是父类中有且不是隐私可以访问,g1在Father中没有,父类中有且公开可以访问

    }
}
class Son extends Father {
    String name = "BB";
    public void g1() {}
    private void show() {
        //super可以访问哪些成员(属性和方法)
        //super直接找父类Father,id在本类没有且父类有不隐私可以访问,f1可以访问,父类的父类不局限也可以一直向上访问
        //name可以访问因为父类没有,g1可以访问,因为父类没有

        //this可以访问哪些成员?
        //this,本类的当然都能访问,id可以,f1可以
    }
}

/*
    第七题
        写出程序的结果
Test
Demo
Rose
Jack
john
Jack
 */
class Test {
    String name = "Rose";
    Test() {
        System.out.println("Test"); // 第一个输出
    }
    Test(String name) {
        this.name = name;// 将John给到自己,因为this可以理解为一个属性,而属性是没有动态绑定机制的
        // 这里其实是将Test类的name更改成为了John,这里一定要注意,我错了,在哪个类就是哪个类的
    }
}

class Demo extends Test {
    String name = "Jack";//8
    Demo() {
        super();  // 这里不写这句话也会默认执行这句话,父类无参构造器
        System.out.println("Demo");  // 第二个输出
    }
    Demo(String s) {
        super(s);  // 父类有参构造器
    }
    public void test() {//4 //(2
        System.out.println(super.name);//第三个输出父类的Rose,第五个输出父类的name已经被修改成了John
        System.out.println(this.name);//四个输出本类的Jack,第六个输出this同理,在哪个类就是哪个this,所以是Jack
    }
    public static void main(String[] args) {
        new Demo().test();//这里没有对象引用是一个匿名对象,走的是Demo的无参构造
        new Demo("john").test();  //走的是本类的带参数构造器
    }
}


// 5
package com.alice.homework01;

public class Homework05 {
    public static void main(String[] args) {

    }
}

/*
    第八题
    扩展如下的BankAccount类
    class BankAccount {
        private double balance;
        public BankAccount(double initialBalance) {
            this.balance = initialBalance;
        }
        public void deposit(double amount) {
            balance += amount;
        }
        public void withdraw(double amount) {
            balance -= amount;
        }
        // set和getBalance方法
    }
    要求:
    1)在上面类的基础上扩展新类CheckingAccount
    对每次存款和取款都收取1美元的手续费
    2)扩展前一个练习的BankAccount类,新类SavingsAccount每个月都有利息产生
    (earnMonthlyInterest方法被调用),并且有每月三次免手续费的存款或取款。
    在earnMonthlyInterest方法中重置交易计数
    3)体会重写的好处
 */
class BankAccount {
    private double balance;
    public BankAccount(double initialBalance) {
        this.balance = initialBalance;
    }
    public void deposit(double amount) {
        balance += amount;
    }
    public void withdraw(double amount) {
        balance -= amount;
    }
    // set和getBalance方法

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
}

class CheckingAccount extends BankAccount {
    public CheckingAccount(double initialBalance) {
        super(initialBalance);
    }

    @Override
    public void deposit(double amount) {
        super.deposit(amount-1);  // tip:在实际应用中父类的方法可能非常复杂,如果我们要重写就非常简单了,只需简单修改
    }

    @Override
    public void withdraw(double amount) {
        super.withdraw(amount+1);
    }
}

class SavingsAccount extends BankAccount {
    private double interest;
    public int freeOfCharge = 3;

    // 老韩添加的是利率,我这里直接添加利息了。。应该添加的是利率的

    public SavingsAccount(double initialBalance) {
        super(initialBalance);
    }

    public double getInterest() {
        return interest;
    }

    public void setInterest(double interest) {
        this.interest = interest;
    }

    public void earnMonthlyInterest() {  // 每个月自动调用
        freeOfCharge = 3;
        setBalance(interest + getBalance());  // 这里应该使用存款考虑手续费的,哈哈
    }

    @Override
    public void deposit(double amount) {
        if (freeOfCharge == 0) {
            super.deposit(amount-1);
            return ;
        }
        super.deposit(amount);
        freeOfCharge--;
    }

    @Override
    public void withdraw(double amount) {
        if (freeOfCharge == 0) {
            super.withdraw(amount+1);
            return ;
        }
        super.withdraw(amount);
        freeOfCharge--;
    }
}

// 6
package com.alice.homework01;

public class Homework06 {
    public static void main(String[] args) {
        new LabeledPoint("Black Thursday", 1929,230.07);
    }
}

/*
    第九题
        设计一个Point类,其x和y坐标可以通过构造器提供。提供一个子类LabeledPoint,其构造器
        接受一个标签值和x,y坐标,比如:new LabeledPoint("Black Thursday", 1929,230.07),
        写出对应的构造器即可。

 */
class Point {
    private double x;
    private double y;

    public Point(double x, double y) {
        setX(x);
        setY(y);
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }
}

class LabeledPoint extends Point {
    private String label;

    public LabeledPoint(String label, double x, double y) {
        super(x, y);
        setLabel(label);
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}


// 7
package com.alice.homework01;

/*
    第十题
    编写Doctor类 {name,age,job,gender,sal}
    相应的get和set方法,五个参数的构造器,重写父类object的equals方法
    并且判断测试类中创建的两个对象是否相等,相等就是判断属性是否相同。
 */


public class Homework07 {
    public static void main(String[] args) {
        Doctor doctor1 = new Doctor("jack", 20, "牙科医生", '男', 20000);
        Doctor doctor2 = new Doctor("jack", 21, "牙科医生", '男', 20000);
        System.out.println(doctor1.equals(doctor2));

    }
}

class Doctor {
    private String name;
    private int age;
    private String job;
    private char gender;
    private double sal;

    public Doctor(String name, int age, String job, char gender, double sal) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.gender = gender;
        this.sal = sal;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    // 重写父类的equals()方法(注意)
    public boolean equals(Object obj) {  // 这里也可以对照源码当中字符串的equals来写
        // public boolean equals(Object obj) 方法中形参为 Object 类型的作用正是为了能够接受
        // 任何 Object 对象及其子类对象。这是 Java 多态(Polymorphism)的体现
        // 因为结果要判断是否相同,所以结果是一个boolean类型
        // 重写:相同的签名(方法名、参数列表)和返回类型
        if (this == obj) {  // 当前对象和要比较的对象应该指向的是堆中的同一个对象,引用类型比较的是地址==
            // 如果是堆中的同一个对象了,那肯定是值相等的了。
            return true;
        }
        // 第二步判断运行类型是不是我们现在这个Doctor类,不是就肯定不是值相同,没必要比
        if(!(obj instanceof Doctor)) {  // 运行类型是Doctor或者其子类,是才可以转型
            return false;
        }
        // 向下转型,将运行类型,编译类型全部确定为Doctor类型,
        // 编译类型确定了能调什么,调自己及其上级,下面这些属性都能调了
        // 运行类型确定方法运行
        Doctor doctor = (Doctor)obj;
        return this.name.equals(doctor.name) && this.age == doctor.age &&
                this.gender == doctor.gender && this.job.equals(doctor.job) &&
                this.sal == doctor.sal;


    }
}

// 8
package com.alice.homework01;

public class Homework08 {
    public static void main(String[] args) {
        Person11 person11 = new Student();  // 向上转
        // person11可以点出来Person11的run和eat,但是当运行的时候才是看运行类型
        person11.eat();  // 看Student,没有找父类Person11
        person11.run();  // 看Student,有,输出Student的
        // 向下转型是将指向子类对象的父类引用转成编译类型为子类的
        Student s = (Student)person11;
        // 现在可以点出子类的了
        s.run();  // 这里运行类型还是Student,所以走的还是Student的
        s.study();
        s.eat();  // 还可以点出父类的
        /*
            总结:向上转型是将子类的引用赋值给父类变量,编译类型为父类,运行类型为子类,
                编译类型为父类可以点出父类的但是点不出子类的,但是运行类型为子类,找的时候
                是从子类找,如果子类有就调用子类的方法,方法受到动态绑定机制的影响,但是属性不受到
                动态绑定的影响。
                向下转型是将指向子类对象的父类引用转换成为编译类型为子类的。可以点出子类也可以点出父类,简单
                来说也是可以点自己和向上点,但是找到方法的时候还是按照运行类型来找。
                向下转型后编译类型和运行类型一样了

         */
    }
}

/*
    第十一题
    现有Person类,里面有方法run,eat,Student类继承了Person类,并重写了run方法,自定义了study方法,试写出
    对象向上转型和向下转型的代码,并写出各自都可以调用的哪些方法,并写出方法输出了什么?
 */
class Person11 {  // 和前面类重名了,这里懒得创建包了
    public void run() {
        System.out.println("person run");
    }

    public void eat() {
        System.out.println("person eat");
    }
}
class Student extends Person11 {
    public void run() {
        System.out.println("student run");
    }
    public void study() {
        System.out.println("student study..");
    }
}

/*
    第十二题
    说出==和equals的区别,简答题
     ==是比较运算符,而equals是Object类的方法,所有的类都有equals方法
     ==可以使用到基本数据类型,如果应用于基本数据类型判断的是值是否相等
     equals不能用于基本数据类型判断
     ==也可以应用于引用数据类型,用于判断两个对象是否是同一个对象
     也就是判断的是内存地址
     equals默认判断两个的值是否相等,一般来说,子类都会重写这个equals方法
     是比较对象的属性值是否相等,String,Integer都是重写了equals方法
 */


// 9
package com.alice.homework01;

public class Homework09 {
    public static void main(String[] args) {
        PersonA[] personArr = new PersonA[4];  // 定义多态数组
        personArr[0] = new Stu("mao", '女', 22, "2025001", "弹吉他");
        personArr[1] = new Teach("bao", '男', 45, 20, "打台球");
        personArr[2] = new Stu("bob", '男', 19, "2025005", "打篮球");
        personArr[3] = new Teach("aby", '女', 28, 3, "唱歌");
        System.out.println("没有排序之前:");
        printArr(personArr);
        BubbleSt bs = new BubbleSt();
        bs.sort(personArr);
        System.out.println("排序之后:");
        printArr(personArr);
        for (int i = 0; i < personArr.length; i++) {
            personArr[i].printCall(personArr[i]);
        }

    }

    public static void printArr(PersonA[] personArr) {
        for (int i = 0; i < personArr.length; i++) {
            System.out.println(personArr[i]);
        }
    }
}

/*
    第十三题
    案例题目描述:
    1、做一个Student类,Student类有名称name,有性别sex,有年龄age,有学号stu_id,做合理的封装,通过构造器在创建对象的时候
    将四个属性赋值。
    2、写一个Teacher类,Teacher类有名称name,性别sex,年龄age,工龄work_age,做合理的封装,通过构造器在创建对象的时候将
    四个属性赋值。
    3、抽取一个父类Person类,将共同的属性和方法放到Person类型中
    4、学生需要有学习方法study,在方法里面写,"我承诺,我会好好学习。"。
    5、教师需要有教学的方法teach,在方法里面写上"我承诺,我会认真教学。"
    6、学生和教师都有玩的方法play,学生玩的是足球,老师玩的是象棋,此方法是返回字符串的,分别返回"xx爱玩足球"和"xx爱玩象棋"(其中xx
    分别代表老师和学生的姓名)。因为玩的方法名称都一样,所以要求此方法定义在父类中,子类实现重写。
    7、定义多态数组,里面保存两个学生和两个教师,要求按照年龄从高到低排序
    8、定义方法,形参为Person类型,功能:调用学生的study或者教师的teach方法
    想要定义这个方法,这个方法应该定义在PersonA中,因为这个多态数组是PersonA的
    并且想要调用学生和教师,运行状态需要是学生或者老师,这里应该需要判断

    功能全部实现了,就是没按照老韩的打印格式来,问题不大。
    总体来说和老师的写的差不多的。
 */
// 创建一个Person类来抽取学生和老师共有的部分
class PersonA {  // 这里重名了换一个名字
    // 抽取属性:名字,姓名,年龄
    private String name;
    private char sex;
    private int age;
    private String hobby;  // 再添加一个兴趣

    // 创建一个构造方法,让子类都用再多于写

    public PersonA(String name, char sex, int age, String hobby) {
        // 使用方法来初始化
        setName(name);
        setSex(sex);
        setAge(age);
        setHobby(hobby);
    }

    // 抽取共有方法,这三个属性的get和set方法

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void play() {
        System.out.println(name + "爱玩" + hobby);
    }

    public void printCall(PersonA personA) {
        if (personA instanceof Stu) {
            Stu s = (Stu) personA;
            s.study();
        } else if (personA instanceof Teach) {
            Teach t = (Teach) personA;
            t.teach();
        }
    }
}

// Teacher类
class Teach extends PersonA {  // 和之前重名了,这里命名为Teach
    // 1、定义属性
    private int work_age;  // 剩下一个特有的属性,工龄

    public Teach(String name, char sex, int age, int work_age, String hobby) {
        super(name, sex, age, hobby);
        setWork_age(work_age);
    }

    public void setWork_age(int work_age) {
        this.work_age = work_age;
    }

    public int getWork_age() {
        return work_age;
    }

    public void teach() {
        System.out.println("我承诺,我会认真教学。");
    }

    @Override
    public void play() {
        System.out.print("我是老师");
        super.play();
    }

    @Override
    public String toString() {
        return "PersonA{" +
                "name='" + getName() + '\'' +
                ", sex=" + getSex() +
                ", age=" + getAge() +
                ", hobby='" + getHobby() +
                ", work_age='" + getWork_age() + '\'' +
                '}';
    }
}

// Student类
class Stu extends PersonA {  // 和之前的Student重复,这里换一个名字Stu
    // 1、定义属性
    private String stu_id;

    // 创建构造器完成创建对象的时候将四个属性赋值,这四个属性我通过set方法来赋值
    public Stu(String name, char sex, int age, String stu_id, String hobby) {
        super(name, sex, age, hobby);
        setStu_id(stu_id);
    }

    public void setStu_id(String stu_id) {
        this.stu_id = stu_id;
    }

    public String getStu_id() {
        return stu_id;
    }

    public void study() {
        System.out.println("我承诺,我会好好学习。");
    }

    @Override
    public void play() {
        System.out.print("我是学生");
        super.play();
    }

    @Override
    public String toString() {
        return "PersonA{" +
                "name='" + getName() + '\'' +
                ", sex=" + getSex() +
                ", age=" + getAge() +
                ", hobby='" + getHobby() +
                ", stu_id='" + getStu_id() + '\'' +
                '}';
    }
}

class BubbleSt {
    public void sort(PersonA[] personArr) {
        int personArrLen = personArr.length;
        for (int i = 0; i < personArrLen - 1; i++) {
            for (int j = 0; j < personArrLen - i - 1; j++) {
                if (personArr[j].getAge() < personArr[j + 1].getAge()) {
                    PersonA temp = personArr[j];
                    personArr[j] = personArr[j + 1];
                    personArr[j + 1] = temp;
                }
            }
        }
    }
}

/*
    第十四题
        程序阅读题在main方法中执行:C c = new C();输出什么内容?
        首先执行C的无参构造方法
 */
class A {
    public A() {
        // 第一条输出的字符串"我是A类",输出完成回去
        System.out.println("我是A类");
    }
}

class B extends A {
    public B() {
        System.out.println("我是B类的无参构造");
    }

    public B(String name) {  //  这里隐藏一个父类的无参构造方法
        System.out.println(name + "我是B类的有参构造");  // 返回到B类型,第二条输出的字符串"haha我是B类的有参构造",回去
    }
}

class C extends B {
    public C() {
        // 然后执行C的有参构造方法
        this("hello");
        System.out.println("我是C类的无参构造");  // 第四条输出的字符串"我是C类的无参构造"
    }
    public C(String name) {
        super("haha");  // 执行父类的有参构造方法
        System.out.println("我是C类的有参构造");  // 第三条输出的字符串"我是C类的有参构造" , 回去
    }
}

/*
    第十五题
    什么是多态,多态具体体现有哪些?
        多态:方法或者对象具有多种形态,是面向对象的第三大特征,是建立在封装和继承基础之上的
        多态的具体体现
       1、方法的多态
       1)重载体现多态2)重写体现多态
       2、对象多态
       1)对象的编译类型和运行类型可以不一致,编译类型在定义的时候就确定了,不能在改变
       2)对象的运行类型是可以变化的,可以通过getClass()来查看运行类型
       3)编译类型看 等号的左边,运行类型看等号的右边

    第十六题
    Java的动态绑定机制是什么?
        1.当调用对象的方法的时候,该方法会和对象的内存地址,内存地址就是在堆中的地址,就是和运行类型进行绑定
        2.当调用对象的属性时,没有动态绑定机制,遵守的是哪里声明哪里使用。
 */
posted @ 2025-05-09 22:37  请叫我虾  阅读(22)  评论(0)    收藏  举报