Chapter08_OOP中级
侧边栏壁纸
  • 累计撰写 53 篇文章
  • 累计收到 5 条评论

Chapter08_OOP中级

bbchen
2023-02-26 / 0 评论 / 48 阅读 / 正在检测是否收录...

面向对象编程(中级)

IDEA 使用

image-20220921145337301

快捷键

File -> Settings -> Keymap

模板

FIle -> Settings -> Editor -> Live Templates

包的作用

  1. 区分相同名字的类
  2. 当类很多时,包可以很好地管理类
  3. 控制访问范围

包的基本语法

package com.hspedu

  1. package 关键字,表示打包
  2. com.hspedu 表示包名

包的本质分析(原理)

包的本质就是创建不同的文件夹(目录)来保存类文件

快速入门

image-20220922103847379

image-20220922104253203

image-20220922104442485

命名规则

只能包含数字、字母、下划线、小圆点,但不能以数字开头,不能是关键字或保留字

命名规范

一般是小写字母 + 小圆点

com.公司名.项目名.业务模块名

image-20220922104946556

常用的包

java.lang.* // lang 包是基本包,默认引入的,不需要再引入

java.util.* // util 包,系统提供的工具包,工具类,使用 Scanner

java.net.* // 网络包,网络并发

java.awt.* // 做 java 界面开发,GUI

细节

我们引入一个包的主要目的是要使用该包下的类

比如 import java.util.Scanner ,就只是引入一个类Scanner

import java.util.* ,表示将 java.util 包所有引入

建议:需要使用哪个类就导入哪个类即可,不建议使用 * 导入

  1. package 的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多有一句 package
  2. import 指令,放在 package 的下面,在类定义前面,可以有多句且没有顺序要求

访问修饰符(modifier)

基本介绍

java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):

  1. 公开级别:用 public 修饰,对外公开
  2. 受保护级别:用 protected 修饰,对子类和同一个包中的类公开
  3. 默认级别:没有修饰符号,向同一个包的类公开
  4. 私有级别:用 private 修饰,只有类本身可以访问,不对外公开

image-20220922113800661

细节

  1. 修饰符可以用来修饰类中的属性、成员方法以及
  2. 只有默认修饰符和 public 才能修饰类
  3. 子类后面再讨论
  4. 成员方法的访问规则和属性完全一样

*封装(encapsulation)

封装是把抽象出的数据(属性)和对数据的操作(方法)封装在一起,数据被保护在内部,程序的其他部分只有通过授权的操作(方法),才能对数据进行操作。

封装的好处

  1. 隐藏实现细节 方法 <-- 调用
  2. 可以对数据进行验证,保证安全合理

实现步骤

  1. 将属性私有化 private【不能直接修改属性】
  2. 提供一个公共的 public set 方法,用于对属性判断并赋值

    public void setXxx(参数列表){

    // 加入数据验证的业务逻辑

    属性 = 参数名;

    }

  3. 提供一个公共的 public get 方法,用于获取属性的值

    public 数据类型 getXxx(){

    // 权限判断,Xxx 某个属性

    return xx;

    }

快速入门

package com.bbedu.encap;

public class Encapsulation01 {

    public static void main(String[] args) {
        Person person = new Person();
        person.setName("Jack");
        person.setAge(30);
        person.setSalary(30000);
        System.out.println(person.info());

        Person tim = new Person("Tim", 2000, 20000);
        System.out.println("======Tim's information======\n" + tim.info());
    }
}

class Person {
    public String name; // 名字公开
    private int age;    // 年龄私有化
    private double salary;

    // 与构造器结合
    public Person() {
    }

    public Person(String name, int age, double salary) {
//        this.name = name;
//        this.age = age;
//        this.salary = salary;
        // 我们可以将set方法写在构造器中,这样仍然可以验证
        setName(name);
        setAge(age);
        setSalary(salary);
    }

    // 自动 set get, alt + insert
    public String getName() {
        return name;
    }

    public void setName(String name) {
        // 加入对数据的校验
        if(name.length() >= 2 && name.length() <= 6){
            this.name = name;
        }else{
            System.out.println("名字长度有误,需要(2-6)字符,默认佚名");
            this.name = "佚名";
        }
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // 判断
        if(age >= 1 && age <= 120){
            this.age = age;
        }else{
            System.out.println("年龄输入有误,要在1-120岁,默认为18");
            this.age = 18;  // 默认年龄
        }
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        // 可以增加当前对象的权限判断
        this.salary = salary;
    }

    // 写一个方法,返回属性信息
    public String info(){
        return "信息为 name=" + name + " age=" + age
                + " salary=" + salary;
    }
}

练习

Account.java

package com.bbedu.encap;

public class Account {
    // 三个属性设为 private
    private String name;
    private double balance;
    private String pwd;

    // 提供两个构造器
    public Account(){
    }

    public Account(String name, double balance, String pwd) {
        this.setName(name);
        this.setBalance(balance);
        this.setPwd(pwd);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if(name.length() >= 2 && name.length() <= 4){
            this.name = name;
        }else{
            System.out.println("姓名输入错误,应为(2-4位),默认为佚名");
            this.name = "佚名";
        }
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        if(balance > 20){
            this.balance = balance;
        }else{
            System.out.println("余额必须(>20), 默认位0");
            this.balance = 0;
        }
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        if(pwd.length() == 6){
            this.pwd = pwd;
        }else {
            System.out.println("密码必须是(6位), 默认为000000");
            this.pwd = "000000";
        }
    }

    //显示账号信息
    public void showInfo() {
        System.out.println("账号信息 name="+ name + " 余额=" + balance + "" +
                " 密码=" + pwd);
    }
}

TestAccount.java

package com.bbedu.encap;

public class TestAccount {
    public static void main(String[] args) {
        // 创建Account
        Account account = new Account();
        account.setName("Jack Chan");
        account.setBalance(6);
        account.setPwd("222");
        account.showInfo();

        Account tim = new Account("Tim", 123, "233233");
        tim.showInfo();
    }
}

*继承

基本介绍

继承可以解决代码复用,让我们的编程更加靠近人类思维,当多个嘞存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过 extends 来声明继承父类即可

image-20220922172407672

基本语法

class 子类 extends 父类{

}

  1. 子类会自动拥有父类定义的属性和方法
  2. 父类又叫超类,基类
  3. 子类又叫派生类

快速入门

image-20220922173952580

package com.bbedu.extend_;

// 父类,是 Pupil 和 Graduate 的父类
public class Student {
    // 共有属性
    public String name;
    public int age;
    private double score;

    // 共有方法
    public void setScore(double score) {
        this.score = score;
    }

    public void showInfo() {
        System.out.println("学生名 " + name +
                " 年龄 " + age +
                " 成绩 " + score);
    }
}
package com.bbedu.extend_;

public class Pupil extends Student{
    public void testing() {
        System.out.println("小学生" + name + "正在考小学数学..");
    }
}
package com.bbedu.extend_;

public class Graduate extends Student{

    public void testing() {
        System.out.println("大学生 " + name + "正在考高等数学..");
    }
}
package com.bbedu.extend_;

public class Extends01 {
    public static void main(String[] args) {
        Pupil pupil = new Pupil();
        pupil.name = "Lily";
        pupil.age = 10;
        pupil.testing();
        pupil.setScore(70);
        pupil.showInfo();

        System.out.println("==========");
        Graduate graduate = new Graduate();
        graduate.name = "Kris";
        graduate.age = 20;
        graduate.testing();
        graduate.setScore(60);
        graduate.showInfo();
    }

}

细节

  1. 子类继承所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性不能直接在子类访问,要通过公共的方法去访问
  2. 子类必须调用父类的构造器,完成父类的初始化
  3. 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会调用父类的无参构造器;如果父类没有无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器去完成对父类的初始化工作,否则编译不会通过
  4. 如果希望指定去调用父类的某个构造器,则需要显示地调用:super(参数列表)
  5. super 必须放在方法的第一行(super 只能在构造器中使用)
  6. super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
  7. java 所有类都是 Object 类的子类,Object 是所有类的基类
  8. 父类构造器的调用不限于直接父类,将一直往上追溯直到 Object 类(顶级父类)
  9. 子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制
  10. 不能滥用继承,子类和父类之间必须要满足 is-a 的逻辑关系

继承的本质

image-20220922204048707

package com.bbedu.extend_;

/**
 * 继承的本质
 */
public class ExtendsTheory {

    public static void main(String[] args) {
        Son son = new Son();    // 内存的布局
        // 要按查找规则返回信息
        // 首先看子类是否有该属性,如果有且能访问,则返回
        // 如果子类没有这个信息,就看父类有没有这个属性,如果有且能访问,则访问
        // 依次向上找
        System.out.println(son.name);
        System.out.println(son.getFatherAge());
        System.out.println(son.hobby);
    }
}

class GrandPa {
    String name = "大头爷爷";
    String hobby = "旅游";
}

class Father extends GrandPa {
    String name = "大头爸爸";
    private int age = 39;

    public int getFatherAge() {
        return age;
    }
}

class Son extends Father {
    String name = "大头儿子";
}

练习

image-20220922205735056

会输出:

a
b name
b

image-20220922205916549

正确

image-20220922205946105

会输出:

我是A类
hahah我是B类的有参构造
我是c类的有参构造
我是c类的无参构造

image-20220922210633636

package com.bbedu.extend_.exercise;

class PC extends Computer {
    private String brand;

    public PC(String cpu, String memory, String drive, String brand) {
        super(cpu, memory, drive);
        this.brand = brand;
    }

    public void printInfo(){
        System.out.println(getDetails() + " brand=" + brand);
    }
}
package com.bbedu.extend_.exercise;

class Computer {
    private String cpu;
    private String memory;
    private String drive;

    public Computer(String cpu, String memory, String drive) {
        this.cpu = cpu;
        this.memory = memory;
        this.drive = drive;
    }

    public String getDetails(){
        return ("CPU型号:" + cpu +
                " 内存大小:" + memory +
                " 硬盘大小:" + drive);
    }
}
package com.bbedu.extend_.exercise;

class NotePad extends Computer {
    private String color;

    public NotePad(String cpu, String memory, String drive, String color) {
        super(cpu, memory, drive);
        this.color = color;
    }

    public void printInfo(){
        System.out.println(getDetails() + " color=" + color);
    }
}
package com.bbedu.extend_.exercise;

public class ExtendsExercise03 {
    public static void main(String[] args) {
        PC pc = new PC("Apple", "16GB", "512GB", "Apple");
        pc.printInfo();

        NotePad notePad = new NotePad("Qualcomm", "6GB", "128GB", "Silver");
        notePad.printInfo();
    }
}

super 关键字

基本介绍

super 代表父类的引用,用于访问父类的属性、方法、构造器

基本语法

  1. 访问父类的属性,但不能访问父类的 private 属性
  2. 访问父类的方法,不能访问父类的 private 方法
  3. 访问父类的构造器:super(参数列表),只能放在构造器的第一句,且只能出现一句

好处、细节

  1. 调用父类的构造器的好处:分工明确,父类属性由父类初始化,子类的属性由子类初始化
  2. 当子类中有和父类中的成员重名时,为了访问父类中的成员,则必须使用 super,若不重名,使用 super、 this 和 直接访问 效果相同
  3. super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用 super 去访问爷爷类的成员,如果多个基类中都有相同名字的成员,使用 super 时遵循就近原则。A -> B -> C
package com.bbedu.super_;

public class Base {

    public int n1 = 999;
    public int age = 111;
    public void cal(){
        System.out.println("Base类的 cal() 方法");
    }

    public void eat() {
        System.out.println("Base类的 eat() 方法");
    }
}
package com.bbedu.super_;

public class A extends Base {

    // 四个属性
    // public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;

    public A(){

    }

    public A(String name){

    }

    public A(String name, int age){

    }

//    public void cal(){
//        System.out.println("A类的 cal() 方法");
//    }

    public void test100(){

    }

    protected void test200(){

    }

    void test300(){

    }

    private void test400() {

    }
}
package com.bbedu.super_;

public class B extends A {

    public int n1 = 888;

    // 访问父类的构造器:super(参数列表),只能放在构造器的第一句,且只能出现一句
    public B() {
//        super();
//        super("Jack");
        super("Tim", 20);
    }

    public void cal() {
        System.out.println("B类的 cal() 方法");
    }

    public void sum() {
        System.out.println("B类的 sum() 方法");
        // 调用父类A的cal方法,有三种方法:
        // cal(): 先找本类,再向父类追溯
        // 若找到但不能访问,则报错,若找不到,则提示不存在
        cal();
        // 等价于 cal()
        this.cal();
        // 没有查找本类的过程,直接查找父类
        super.cal();

        // 访问属性的规则, n1 和 this.n1 相同
        // 本类没有则查找父类
        System.out.println(n1);
        System.out.println(this.n1);
        System.out.println(super.n1);
        System.out.println(age);
        eat();
    }

    // 访问父类的属性,但不能访问父类的 private 属性
    public void hi() {
        System.out.println(super.n1 + " " + super.n2 + " " + super.n3);
    }

    // 访问父类的方法,不能访问 private 方法
    public void ok() {
//        super.test100();
//        super.test200();
        super.test300();
    }
}
package com.bbedu.super_;

public class super01 {
    public static void main(String[] args) {
        B b = new B();
        b.sum();
    }
}

super 和 this 的比较

No.区别点thissuper
1访问属性访问本类中的属性,如果本类没有则从父类继续查找从父类开始查找属性
2调用方法访问本类中的方法,如果本类没有,则从父类继续查找从父类开始查找方法
3调用构造器调用本类构造器,必须放在构造器的首行调用父类的构造器,必须放在子类构造器的首行
4特殊表示当前对象子类中访问父类对象

方法重写 / 覆盖(override)

基本介绍

方法重写就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法

细节

  1. 子类的方法的参数,方法名称,要和父类方法一致
  2. 子类方法的返回类型和父类返回方法一致,或是父类返回类型的子类
  3. 子类方法不能缩小父类方法的访问权限

练习

名称发生范围方法名参数列表返回类型修饰符
重载(overload)本类必须一样类型,个数或顺新至少有一个不同无要求无要求
重写(override)父子类必须一样相同一致或子是父的子类子类不能缩小

image-20220923161417669

package com.bbedu.override_;

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

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

    public String say(){
        String s = "name = " + this.name + " age = " + this.age;
        return s;
    }
}
package com.bbedu.override_;

public class Student extends Person{
    private String id;
    private int score;

    public Student(String name, int age, String id, int score) {
        super(name, age);
        this.id = id;
        this.score = score;
    }

    @Override
    public String say() {
        return super.say() + " id = " + id +
                " score = " + score;
    }
}
package com.bbedu.override_;

public class OverrideExercise {
    public static void main(String[] args) {
        Person jack = new Person("Jack", 35);
        System.out.println(jack.say());

        Student student = new Student("Tim", 20, "123456", 100);
        System.out.println(student.say());
    }
}

*多态(polymorphic)

基本介绍

方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承的基础之上的

  1. 重写和重载就体现多态
  2. 对象的多态(核心)

    (1) 一个对象的编译类型和运行类型可以不一致

    image-20220923164226651

    (2) 编译类型在定义对象时,就确定了,不能改变

    (3) 运行类型是可以变化的

    (4) 编译类型看定义时 = 的左边,运行类型看 = 的右边

package com.bbedu.poly_.objectpoly_;

public class Animal {
    public void cry(){
        System.out.println("Animal 动物在叫...");
    }
}
package com.bbedu.poly_.objectpoly_;

public class Dog extends Animal {

    public void cry(){
        System.out.println("Dog 小狗在叫...");
    }
}
package com.bbedu.poly_.objectpoly_;

public class Cat extends Animal {

    public void cry(){
        System.out.println("Cat 小猫在叫...");
    }
}
package com.bbedu.poly_.objectpoly_;

public class PolyObject {

    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.cry();

        animal = new Cat();
        animal.cry();
    }
}

image-20220923230305556

image-20220923230626365

细节

*多态的前提是:两个对象(类)存在继承关系

多态的向上转型

  1. 本质:父类的引用指向了子类的对象
  2. 语法:父类类型 引用名 = new 子类类型();
  3. 特点:

    1. 编译类型看左边,运行类型看右边
    2. 可以调用父类中的所有成员
    3. 无法调用子类的特有成员,因为在编译阶段,能调用那些成员,是由编译类型来绝决定的
    4. 最终的运行效果看子类的具体实现
package com.bbedu.poly_.detail_;

public class Animal {
    String name = "动物";
    int age = 10;
    public void sleep(){
        System.out.println("睡");
    }
    public void run(){
        System.out.println("跑");
    }
    public void eat(){
        System.out.println("吃");
    }
    public void show(){
        System.out.println("hello 你好");
    }
}
package com.bbedu.poly_.detail_;

public class Cat extends Animal{

    public void eat(){
        System.out.println("Cat 猫吃鱼");
    }

    public void catchMouse(){
        System.out.println("Cat 猫猫抓老鼠");
    }
}
package com.bbedu.poly_.detail_;

public class PolyDetail {

    public static void main(String[] args) {
        // 向上转型,父类的引用指向了子列的对象
        Animal animal = new Cat();
        Object object = new Cat(); // 可行
        // (1)可以调用父类中的所有成员
        // animal.catchMouse(); // 错误,(2)无法调用子类的特有成员
        // (3)因为在编译阶段,能调用那些成员,是由编译类型来绝决定的

        // (4)最终的运行效果看子类的具体实现
        // 调用方法时,按照从子类开始查找方法,规则与前面的方法调用一致
        animal.eat();
        animal.run();
        animal.show();
        animal.sleep();
    }
}

多态的向下转型

  1. 语法:子类类型 引用名 = (子类类型) 父类引用;
  2. 只能强转父类的引用,不能强转父类的对象
  3. 要求父类的引用必须指向的是当前目标类型的对象
  4. 当向下转型后,可以调用子类类型中的所有成员

细节

  • 属性没有重写之说,属性的值看编译类型

    package com.bbedu.poly_.detail_;
    
    public class PolyDetail02 {
        public static void main(String[] args) {
            Sub sub = new Sub();
            System.out.println(sub.count);
            Base base = new Sub();
            System.out.println(base.count);
        }
    }
    
    class Base {
        int count = 10;
    }
    
    class Sub extends Base {
        int count = 20;
    }
  • instanceof 比较操作符,用于判断对象 的运行类型是否为XX类型或XX类型的子类型

    package com.bbedu.poly_.detail_;
    
    public class PolyDetail03 {
        public static void main(String[] args) {
            BB bb = new BB();
            System.out.println(bb instanceof BB);   // true
            System.out.println(bb instanceof AA);   // true
    
            // aa 编译类型 AA, 运行类型 BB
            AA aa = new BB();
            System.out.println(aa instanceof AA);   // true
            System.out.println(aa instanceof BB);   // true
    
            Object obj = new Object();
            System.out.println(obj instanceof AA);  // false
            String str = "hello";
            System.out.println(str instanceof Object);  // true
        }
    }
    
    class AA {
    
    }
    
    class BB extends AA {
    
    }
    

练习

image-20220925164151859

image-20220925164957355

package com.bbedu.poly_;

public class PolyExercise02 {
    public static void main(String[] args) {
        Sub sub = new Sub();
        System.out.println(sub.count);
        sub.display();
        Base b = sub;
        System.out.println(sub == b);   
        System.out.println(b.count);
        b.display();
    }
}

class Base {
    int count = 10;
    public void display(){
        System.out.println(this.count);
    }
}

class Sub extends Base{
    int count = 20;
    public void display(){
        System.out.println(this.count);
    }
}

属性看编译,方法看运行

java 的动态绑定机制 (重要)

  1. 当调用对象方法时,该方法会和该对象的内存地址/运行类型 绑定
  2. 当调用属性时,没有动态绑定机制,哪里声明,哪里使用
package com.bbedu.poly_.danamic_;

public class DynamicBinding {
    public static void main(String[] args) {
        A a = new B();
        // 子类中有的话,为40
        // 子类没有的话,getI()调用子类的,此为动态绑定,20+10,为30
        System.out.println(a.sum());
        // 属性没有动态绑定,10+10,为20
        System.out.println(a.sum1());
    }
}

class A{
    public int i = 10;
    public int sum(){
        return getI() + 10;
    }

    public int getI() {
        return i;
    }

    public int sum1() {
        return i + 10;
    }
}

class B extends A {
    public int i = 20;
//    public int sum() {
//        return i + 20;
//    }

    @Override
    public int getI() {
        return i;
    }

//    public int sum1() {
//        return i + 10;
//    }
}

多态数组

数组的定义类型为父类类型,里面保存的实际元素类型为子类类型

package com.bbedu.poly_.polyarr_;

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

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

    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 say() {
        return "name = " + name + "\tage = " + age;
    }
}
package com.bbedu.poly_.polyarr_;

public class Student extends Person {
    private double score;

    public Student(String name, int age, double score) {
        super(name, age);
        this.score = score;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String say() {
        return super.say() + "\tscore=" + score;
    }

    public void study() {
        System.out.println("学生 " + getName() + " 正在学习");
    }
}
package com.bbedu.poly_.polyarr_;

public class Teacher extends Person{
    private double salary;

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String say() {
        return super.say() + "\tsalary=" + salary;
    }

    public void teach() {
        System.out.println("老师 " + getName() + " 正在上课");
    }
}
package com.bbedu.poly_.polyarr_;

public class PolyArray {
    public static void main(String[] args) {
        // 1 Person、2 Student、1 Teacher
        Person[] persons = new Person[5];
        persons[0] = new Person("Tim", 20);
        persons[1] = new Student("Sam", 20, 80);
        persons[2] = new Student("Amy", 30, 60);
        persons[3] = new Teacher("Rain", 50, 20000);
        persons[4] = new Teacher("Peter", 34, 14000);

        for (int i = 0; i < persons.length; i++) {
            // person[i] 的编译类型都为 Person,运行类型根据实际情况
            System.out.println(persons[i].say());
            // 判断运行类型,向下转型
            if(persons[i] instanceof Student){
//                Student s = (Student) persons[i];
//                s.study();
                ((Student) persons[i]).study();
            }
            else if(persons[i] instanceof Teacher){
//                Teacher t = (Teacher) persons[i];
//                t.teach();
                ((Teacher) persons[i]).teach();
            }
            else {
                System.out.println("不是学生也不是老师");
            }
        }
   }
}

多态参数

image-20220925213023497

package com.bbedu.poly_.polyparameter_;

public class Employee {
    private String name;
    private double salary;

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public double getAnnual() {
        return 12 * salary;
    }

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}
package com.bbedu.poly_.polyparameter_;

public class Worker extends Employee {
    public Worker(String name, double salary) {
        super(name, salary);
    }
    public void work(){
        System.out.println("员工 " + getName() + " is working");
    }

    @Override
    public double getAnnual() {
        // 直接调用父类方法
        return super.getAnnual();
    }
}
package com.bbedu.poly_.polyparameter_;

public class Manager extends Employee {
    private double bonus;

    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    public void manage(){
        System.out.println("经理 " + getName() + " is managing");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual() + bonus;
    }
}
package com.bbedu.poly_.polyparameter_;

public class PolyParameter {
    public static void main(String[] args) {
        Worker tom = new Worker("Tom", 7000);
        Manager sam = new Manager("Sam", 10000, 30000);
        PolyParameter polyParameter = new PolyParameter();
        polyParameter.showEmpAnnual(tom);
        polyParameter.showEmpAnnual(sam);
        polyParameter.testWork(tom);
        polyParameter.testWork(sam);
    }

    public void showEmpAnnual(Employee e) {
        System.out.println(e.getAnnual());
    }

    public void testWork(Employee e){
        // 向下转型
        if(e instanceof Worker) {
            ((Worker) e).work();
        }else if(e instanceof Manager){
            ((Manager) e).manage();
        }else {
            System.out.println("不做处理...");
        }
    }
}

Object 类

image-20220925213345366

equals 方法

== 和 equals 的对比

== 是一个比较运算符

  1. 既可以判断基本类型,又可以判断引用类型
  2. 如果判断基本类型,判断的是 值 是否相等
  3. 如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象

euqals 方法

  1. euqals 是Object 类中的方法,只能判断引用类型
  2. 默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。比如 Integer, String

练习

image-20220926103935772

package com.bbedu.object_;

public class EuqalsExercise01 {

    public static void main(String[] args) {
        Person person = new Person("Tom", 10, '男');
        Person person1 = new Person("Tom", 10, '男');
        Person person2 = new Person("Jack", 20, '男');

        System.out.println(person.equals(person1));     // 默认为false, Object 比较的是地址
        System.out.println(person.equals(person2));
    }
}

class Person {
    private String name;
    private int age;
    private char gender;

    @Override
    public boolean equals(Object obj) {
        // 如果比较的对象是同一个,则直接返回true
        if (this == obj){   // this 即为调用此方法的当前对象
            return true;
        }
        if(obj instanceof Person){  //类型是Person才比较
            Person p = (Person) obj;
            return this.name.equals(this.name) && this.age == p.age
                    && this.gender == p.gender;
//            if (((Person) obj).age == this.age &&
//            ((Person) obj).name.equals(this.name) &&
//            ((Person) obj).gender == this.gender){
//                return true;
//            }
        }
        return false;
    }

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

    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 char getGender() {
        return gender;
    }

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

image-20220926105205531

false/true/false/true/false

image-20220926110054033

true/true/true/false/true/编译错误(不是同一种对象)

字符的本质是整数

hashCode

返回该对象的哈希码值

  1. 提高哈结构的容器的效率
  2. 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
  3. 两个引用,如果指向的是不同对象,则哈希值是不一样的
  4. 哈希值主要是根据地址来计算的,但不能完全等价为地址
  5. 示例
  6. 后面的集合中再重写该方法
package com.bbedu.object_;

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

        AA aa = new AA();
        AA aa2 = new AA();
        AA aa3 = aa;
        System.out.println("aa.hashCode()=" + aa.hashCode());
        System.out.println("aa2.hashCode()=" + aa2.hashCode());
        System.out.println("aa3.hashCode()=" + aa3.hashCode());
    }
}

class AA 

toString

  • 返回该对象的字符串表示
  • 默认返回:全类型+@+哈希值的十六进制
  • 重写 toString 方法,打印对象或拼接对象式,都会自动调用该对象的 toString 形式
  • 当直接输出一个对象时,toString 方法就会默认调用该对象的 toString 方法
package com.bbedu.object_;

public class ToString_ {
    public static void main(String[] args) {
        /*
        jdk 源码
                public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
         */

        Monster monster = new Monster("妖怪", "巡山", 2000);
        System.out.println(monster.toString());
        System.out.println(monster.hashCode() + " HEX: " + Integer.toHexString(monster.hashCode()));
        // 直接输出一个对象时,toString 方法就会默认调用该对象的 toString 方法
        System.out.println(monster);
    }
}

class Monster {
    private String name;
    private String job;
    private double sal;


    // 重写输出对象的属性
    @Override
    public String toString() {  // 一般是输出对象的属性
        return "Monster{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                '}';
    }

    public Monster(String name, String job, double sal) {
        this.name = name;
        this.job = job;
        this.sal = sal;
    }
}

finalize (废弃)

当对象被回收时,系统自动会调用该对象的 finalize 方法,子类可以重写该方法,做一些释放资源的操作

什么时候被回收:当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会调用 finalize() 方法

断点调试 (debug)

需求

断点调试可以一步一步的看源码执行的过程,从而发现错误所在

在断点调试过程中,是运行状态,是以对象的运行类型来执行的

介绍

  1. 断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。进行分析从而找到这个Bug
  2. 断点调试是程序员必须掌握的技能。
  3. 断点调试也能帮助我们查看java底层源代码的执行过程;提高程序员的Java水平。

快捷键

F7 跳入 F8 跳过、逐行执行 shift + F8 跳出 F9 resume, 执行到下一个断点

案例

1.

package com.bbedu.debug_;

public class Debug01 {
    public static void main(String[] args) {
        // 演示逐行执行
        int sum = 0;
        for (int i = 0; i < 5; i++) {
            sum += i;
            System.out.println("i=" + i);
            System.out.println("sum=" + sum);
        }
        System.out.println("退出for...");
    }
}

image-20220926191133850

2.

package com.bbedu.debug_;

public class Debug02 {
    public static void main(String[] args) {
        int[] arr = {1, 10, -1};
        for (int i = 0; i <= arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("退出for...");
    }
}

image-20220926191841921

  1. 强制进入,查看源码
package com.bbedu.debug_;

import java.util.Arrays;

public class Debug03 {
    public static void main(String[] args) {
        int[] arr = {8, -1, 10, 98, 45};
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}

image-20220926192830573

  1. resume, 动态下断点
package com.bbedu.debug_;

import java.util.Arrays;

public class Debug04 {
    public static void main(String[] args) {
        int[] arr = {8, -1, 10, 98, 45};
        Arrays.sort(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }

        System.out.println("Hello100");
        System.out.println("Hello200");
        System.out.println("Hello300");
        System.out.println("Hello400");
        System.out.println("Hello500");
        System.out.println("Hello600");
    }
}

image-20220926193702737

jdk 源码也可下断点调试,不能到的会有下图显示:

image-20220926193845827

练习

image-20220926194137858

项目实战-零钱通

image-20220926195729350

化繁为简

  1. 先完成显示菜单,并且可以选择,给出对应的提示信息
  2. 完成零钱通明细
  3. 完成收益入账
  4. 消费
  5. 退出,确认退出
  6. 判断入账和消费金额是否合理
  7. 将面向过程的代码改为面向对象的

image-20220927134424208

面向过程版本:

package com.bbedu.smallchange;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

import static java.lang.Thread.sleep;

public class SmallChangeSys {
    public static void main(String[] args) throws InterruptedException {

        // 定义相关变量
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        String key = "";

        String details = "\n------------------零钱通明细------------------";

        double money = 0;
        double balance = 0;
        Date date = null;   // Date 是 java.util.Date 类型,表示日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String note = null;
        String confirm = null;


        do {

            System.out.println("\n------------------零钱通菜单------------------");
            System.out.println("\t\t\t1 零钱通明细");
            System.out.println("\t\t\t2 收 益 入 账");
            System.out.println("\t\t\t3 消     费");
            System.out.println("\t\t\t4 退     出");

            System.out.print("请选择(1-4):");
            key = scanner.next();

            switch (key){
                case "1":
                    System.out.println(details);
                    break;
                case "2":
                    System.out.print("收益入账金额:");
                    money = scanner.nextDouble();
                    // money 应该校验
                    // 不合理的直接退出
                    if (money <= 0) {
                        System.out.println("! 收益入账金额需要大于0");
                        break;
                    }
                    balance += money;
                    date = new Date();
                    // 日期格式化
                    details += "\n收益入账\t" + "+¥" + money
                            + "\t" + sdf.format(date) + " 余额:" + balance;
                    break;
                case "3":
                    System.out.println("消费金额:");
                    money = scanner.nextDouble();
                    // 校验
                    if ( money <= 0 || money > balance){
                        System.out.println("! 消费金额应在 (0-"+balance+")");
                        break;
                    }
                    System.out.println("消费说明:");
                    note = scanner.next();
                    balance -= money;
                    date = new Date();

                    details += "\n" + note + "\t-¥" + money + "\t" +
                            sdf.format(date) + "\t余额:" + balance;

                    break;
                case "4":
                    // 编程遵守原子性
                    while (true){
                        System.out.println("确定要退出吗? (y/n)");
                        confirm = scanner.next();
                        if(confirm.equals("y") || confirm.equals("n")){
                            break;
                        }else {
                            System.out.println("! 输入有误, 请重新输入");
                        }
                    }
                    if (confirm.equals("y")){
                        System.out.print(" 退 出 中");
                        for (int i = 0; i < 3; i++) {
                            Thread.sleep(300);
                            System.out.print(" .");
                        }
                        System.out.println();
                        loop = false;
                    }
                    break;
                default:
                    System.out.println("! 选择有误,请重新选择");

            }
        }while (loop);

        System.out.println("-----零钱通已退出-----");
    }
}

面向对象版本:

package com.bbedu.smallchange.oop;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

/**
 * 该类完成零钱通的各个功能
 * 使用OOP
 * 将各个功能对应应该方法
 */
public class SmallChangeSysOOP {
    // 定义相关变量
    boolean loop = true;
    Scanner scanner = new Scanner(System.in);
    String key = "";

    String details = "\n------------------零钱通明细------------------";

    double money = 0;
    double balance = 0;
    Date date = null;   // Date 是 java.util.Date 类型,表示日期
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    String note = null;
    String confirm = null;

    public void showTab(){
        do {

            System.out.println("\n------------------零钱通选择菜单------------------");
            System.out.println("\t\t\t1 零钱通明细");
            System.out.println("\t\t\t2 收 益 入 账");
            System.out.println("\t\t\t3 消     费");
            System.out.println("\t\t\t4 退     出");

            System.out.print("请选择(1-4):");
            key = scanner.next();

            switch (key){
                case "1":
                    detail();
                    break;
                case "2":
                    income();
                    break;
                case "3":
                    pay();
                    break;
                case "4":
                    exit();
                    break;
                default:
                    System.out.println("! 选择有误,请重新选择");

            }
        }while (loop);
    }

    public void detail(){
        System.out.println(details);
    }

    public void income(){

        System.out.print("收益入账金额:");
        money = scanner.nextDouble();
        // money 应该校验
        // 不合理的直接退出
        if (money <= 0) {
            System.out.println("! 收益入账金额需要大于0");
            return; // 退出方法,不在执行后面的代码
        }
        balance += money;
        date = new Date();
        // 日期格式化
        details += "\n收益入账\t" + "+" + money
                + "\t" + sdf.format(date) + " 余额:" + balance;
    }

    public void pay(){
        System.out.println("消费金额:");
        money = scanner.nextDouble();
        // 校验
        if ( money <= 0 || money > balance){
            System.out.println("! 消费金额应在 (0-"+balance+")");
            return;
        }
        System.out.println("消费说明:");
        note = scanner.next();
        balance -= money;
        date = new Date();

        details += "\n" + note + "\t-" + money + "\t" +
                sdf.format(date) + "\t余额:" + balance;
    }

    public void exit() {
        // 编程遵守原子性
        while (true){
            System.out.println("确定要退出吗? (y/n)");
            confirm = scanner.next();
            if(confirm.equals("y") || confirm.equals("n")){
                break;
            }else {
                System.out.println("! 输入有误, 请重新输入");
            }
        }
        if (confirm.equals("y")){
            System.out.println(" 退 出 中");
            loop = false;
        }
        System.out.println("-----零钱通已退出-----");
    }

}
package com.bbedu.smallchange.oop;

public class SmallChangeSysApp {
    public static void main(String[] args) {
        SmallChangeSysOOP smallChangeSysOOP = new SmallChangeSysOOP();
        smallChangeSysOOP.showTab();
    }
}

本章练习

image-20220927214446601

package com.bbedu.homework;

public class Homework01 {
    public static void main(String[] args) {
        // 对象数组,注意声明方式:
        Person[] people = new Person[3];
        people[0] = new Person("Jack", 30, "Coder");
        people[1] = new Person("Tim", 20, "teacher");
        people[2] = new Person("Mary", 40, "seller");

        for (int i = 0; i < people.length; i++) {
            System.out.println(people[i]);
        }

        // 冒泡排序
        for (int i = 0; i < people.length - 1; i++) {
            for (int j = 0; j < people.length - i -1; j++) {
                if (people[j].getAge() < people[j+1].getAge()){
                    int tmp = people[j].getAge();
                    people[j].setAge(people[j+1].getAge());
                    people[j+1].setAge(tmp);
                }
            }
        }
        System.out.println("===排序后===");
        for (int i = 0; i < people.length; i++) {
            System.out.println(people[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 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;
    }

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

image-20220927214502988

image-20220927214520417

package com.bbedu.homework;

public class Homework03 {
    public static void main(String[] args) {
        Professor professor = new Professor("Cook", 50, "CEO", 1500000, 1.3);
        professor.introduce();
    }
}

class Teacher{
    private String name;
    private int age;
    private String post;
    private double salary;
    private double grade;

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

    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 getPost() {
        return post;
    }

    public void setPost(String post) {
        this.post = post;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public double getGrade() {
        return grade;
    }

    public void setGrade(double grade) {
        this.grade = grade;
    }

    public void introduce(){
        System.out.print("name=" + name + " age=" + age
                            + " post=" + post + " salary=" + salary);
    }

}

class Professor extends Teacher{

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

    @Override
    public void introduce() {
        super.introduce();
        System.out.println(" grade=" + this.getGrade());
    }
}

image-20220927214547675

package com.bbedu.homework;

public class Homework04 {
    public static void main(String[] args) {
        Worker tim = new Worker("Tim", 100, 30);
        tim.printSalary();
        Manager cook = new Manager("Cook", 300, 20);
        cook.printSalary();
    }
}

class Employee {
    private String name;
    private double dayPay;
    private int workDay;

    public Employee(String name, double dayPay, int workDay) {
        this.name = name;
        this.dayPay = dayPay;
        this.workDay = workDay;
    }

    public String getName() {
        return name;
    }

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

    public double getDayPay() {
        return dayPay;
    }

    public void setDayPay(double dayPay) {
        this.dayPay = dayPay;
    }

    public int getWorkDay() {
        return workDay;
    }

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

    public void printSalary(){
        System.out.print("name=" + name + " dayPay=" + dayPay
                + "workDay="+ workDay);
    }
}

class Worker extends Employee{
    public Worker(String name, double dayPay, int workDay) {
        super(name, dayPay, workDay);
    }

    @Override
    public void printSalary() {
        System.out.print("Worker ");
        super.printSalary();
        System.out.println(" salary=" + getWorkDay()*getDayPay()*1.0);
    }
}

class Manager extends Employee{
    public Manager(String name, double dayPay, int workDay) {
        super(name, dayPay, workDay);
    }

    @Override
    public void printSalary() {
        System.out.print("Manager ");
        super.printSalary();
        System.out.println(" salary=" + getWorkDay()*getDayPay()*1.2);
    }
}

image-20220928142751033

package com.bbedu.homework.homework5;

public class Test {
    public static void main(String[] args) {
        Employee[] e = new Employee[5];
        e[0] = new Worker("Sam", 100);
        e[1] = new Waiter("Peter", 120);
        e[2] = new Peasant("Tony", 80);
        e[3] = new Teacher("Mary", 150, 20);
        e[4] = new Scientist("Bob", 200, 100000);

        for (int i = 0; i < e.length; i++) {
            e[i].printSal();
        }
    }
}
package com.bbedu.homework.homework5;

public class Employee {
    private String name;
    private double sal;

    public Employee(String name, double sal) {
        this.name = name;
        this.sal = sal;
    }

    public String getName() {
        return name;
    }

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

    public double getSal() {
        return sal;
    }

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

    public void printSal(){
        System.out.println("name=" + name + " salary=" + sal*365);
    }
}
package com.bbedu.homework.homework5;

public class Worker extends Employee {
    public Worker(String name, double sal) {
        super(name, sal);
    }

    @Override
    public void printSal() {
        System.out.print("Worker ");
        super.printSal();
    }
}
package com.bbedu.homework.homework5;

public class Peasant extends Employee {
    public Peasant(String name, double sal) {
        super(name, sal);
    }

    @Override
    public void printSal() {
        System.out.print("Peasant ");
        super.printSal();
    }
}
package com.bbedu.homework.homework5;

public class Teacher extends Employee {
    private double dayPay;

    public Teacher(String name, double sal, double dayPay) {
        super(name, sal);
        this.dayPay = dayPay;
    }

    public double getDayPay() {
        return dayPay;
    }

    public void setDayPay(double dayPay) {
        this.dayPay = dayPay;
    }

    @Override
    public void printSal() {
        System.out.print("Teacher ");
        System.out.println("name=" + getName() + " salary=" + (getSal()+getDayPay())*365);
    }
}
package com.bbedu.homework.homework5;

public class Scientist extends Employee{
    private double bonus;

    public Scientist(String name, double sal, double bonus) {
        super(name, sal);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    @Override
    public void printSal() {
        System.out.print("Scientist ");
        System.out.println("name=" + getName() + " salary=" + (getSal()*365+getBonus()));
    }
}
package com.bbedu.homework.homework5;

public class Waiter extends Employee{
    public Waiter(String name, double sal) {
        super(name, sal);
    }

    @Override
    public void printSal() {
        System.out.print("Waiter ");
        super.printSal();
    }
}

image-20220928145606122

image-20220928182856479

image-20220928182907314

image-20220928183312196

package com.bbedu.homework.homework8;

public 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;
    }

    public double getBalance() {
        return balance;
    }
}
package com.bbedu.homework.homework8;

public class CheckingAccount extends BankAccount {

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

    @Override
    public void deposit(double amount) {
        super.deposit(amount - 1);
    }

    @Override
    public void withdraw(double amount) {
        super.withdraw(amount + 1);
    }
}
package com.bbedu.homework.homework8;

public class SavingAccount extends BankAccount{
    private int freeCount = 3;
    private double rate = 0.01; // 利率

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

    public int getFreeCount() {
        return freeCount;
    }

    public void setFreeCount(int freeCount) {
        this.freeCount = freeCount;
    }

    public double getRate() {
        return rate;
    }

    public void setRate(double rate) {
        this.rate = rate;
    }

    @Override
    public void deposit(double amount) {
        if (freeCount > 0){
            super.deposit(amount);
        } else {
            super.deposit(amount - 1);
        }
        freeCount--;
    }

    @Override
    public void withdraw(double amount) {
        if (freeCount > 0){
            super.withdraw(amount);

        } else {
            super.withdraw(amount + 1);
        }
        freeCount--;
    }

    public void earnMonthlyInterest(){
        freeCount = 3;
        super.deposit(getBalance()*rate);
    }
}
package com.bbedu.homework.homework8;

public class Homework08 {
    public static void main(String[] args) {
//        CheckingAccount checkingAccount = new CheckingAccount(1000);
//        checkingAccount.deposit(100);
//        checkingAccount.withdraw(10);
//        System.out.println(checkingAccount.getBalance());

        SavingAccount savingAccount = new SavingAccount(1000);
        savingAccount.deposit(100);
        savingAccount.deposit(100);
        savingAccount.deposit(100);
        System.out.println(savingAccount.getBalance());
        savingAccount.deposit(100);
        System.out.println(savingAccount.getBalance());
        savingAccount.earnMonthlyInterest();
        savingAccount.deposit(100);
        System.out.println(savingAccount.getBalance());
    }
}

image-20220928191409626

public LabeledPoint(String label, double x, double y) {
    super(x, y);
    this.label = label;
}

image-20220928192033058

package com.bbedu.homework.homework10;

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

    public Doctor(String name, int age, String job, String 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 String getGender() {
        return gender;
    }

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

    public double getSal() {
        return sal;
    }

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

    @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }

        if(!(obj instanceof Doctor)){
            return false;
        }

        Doctor doctor = (Doctor) obj;
        return doctor.age == this.age && doctor.sal == this.sal
                && doctor.name.equals(this.name) && doctor.job.equals((this.job))
                && doctor.gender.equals(this.gender);
    }
}

image-20220928192824217

package com.bbedu.homework.homework11;

import java.rmi.StubNotFoundException;

public class Homework11 {
    public static void main(String[] args) {
        // 向上转型
        Person p = new Student();
        // 可以用 Person 的 eat()和 run() 方法, 但run方法被Student类重写
        // 不能调用子类的特有方法, 因为编译类型为父类
        p.eat();
        p.run();

        // 向下转型
        Student s = (Student) p;
        // 可以调用子类的所有方法
        s.run();
        s.eat();
        s.study();
    }
}

image-20220928194352106

image-20220928194413855

image-20220928203152076

image-20220928220447240

image-20220928220859039

0

评论

博主关闭了所有页面的评论