小白学习笔记(Java面向对象进阶)

Java面向对象核心概念解析

this关键字:

this是什么?

它在方法内部使用,表示调用该方法的对象

他在构造器内部使用,表示该构造器正在初始化的对象

this可以调用的结构:成员变量,方法和构造器

this的理解:当前对象(在方法中调用时)或当前正在创建的对象(在构造器中调用时)

用this弄出来的就是属性,没有的就是形参

举例:

public class PersonTest {
    public static void main(String[] args) {
        Person person = new Person();
        person.setAge(20);
        System.out.println(person.getAge());
    }
}

class Person{
    String name;
    int age;


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

this调用属性和方法:

针对于方法内的使用情况:(准确的说是非static修饰的方法)

一般来说,我们通过对象调用方法,可以在方法内调用当前对象的属性或其他方法。此时,我们可以在属性和其他方法前使用“this”,表示当前属性或方法所属的对象,但是一般情况下,我们都选择省略此“this”结构

特殊情况:如果方法的形参和对象的属性名重名了,就不能省略。使用this修饰的变量就是属性(成员变量),没有使用的就是形参

针对于构造器的使用情况类似:

比如:

public class PersonTest {
    public static void main(String[] args) {
        Person person = new Person("tom");
        person.setAge(20);
        System.out.println(person.getAge());
    }
}

class Person{
    String name;
    int age;


    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
    public Person(String name){
        this.name = name;
    }
}

this调用构造器:

我们使用this(形参列表)这个格式,调用当前类中指定的构造器

要求this(形参列表)必须在当前构造器的首行

这个格式在构造器中最多声明1个

举例:

public class Users {
    String name;
    int age;


    public Users() {
        //要编写的50行代码
    }

    public Users(String name) {
        this();//代表上面的构造器
        this.name = name;
    }

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

练习1:

创建的类:

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

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

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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


    public void marry(Girl girl) {
        System.out.println("嫁给我!");
    }
    public void shout(){
        if(this.age >= 18){
            System.out.println("就是现在!!!!");
        }else {
            System.out.println("算了吧,你不配");
        }
    }


}
public class Girl {
    private String name;
    private int age;

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

    public Girl() {
    }

    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 void marry(Boy boy) {
        System.out.println("你爱我吗?会娶我吗?" + boy.getName());
    }



public int compare(Girl girl) {
    if (this.age > girl.age) {
        return 1;
    } else if (this.age < girl.age) {
        return -1;
    } else {
        return 0;
    }
}

}

创建的对象:

public class BoyGirlTest {
    public static void main(String[] args) {
        Boy boy = new Boy("妄汐霜",19);
        Girl girl = new Girl("绫波丽",19);

        girl.marry(boy);
        boy.marry(girl);
        boy.shout();


        Girl girl1 = new Girl("明日香",20);
        int num =girl1.compare(girl);
        if(num > 0){
            System.out.println(girl.getName());
        } else if (num < 0) {
            System.out.println(girl1.getName());
        }else{
            System.out.println("小孩子才做选择");
        }


    }
}

练习2:

创建的类:

package corm.atguigu01._this.exer3;

/**
 * ClassName:Account
 * Package:corm.atguigu01._this.exer3
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/5 20:55
 * @Version 1.0
 */
public class Account {
    private double balance;

    public Account(double init_balance) {
        this.balance = init_balance;
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("成功存入" + balance + "元");
        }
    }

    public void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println("成功取出" + amount + "元");
        } else {
            System.out.println("你没有那么多钱");
        }

    }

}
package corm.atguigu01._this.exer3;

/**
 * ClassName:Customer
 * Package:corm.atguigu01._this.exer3
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/5 21:01
 * @Version 1.0
 */
public class Customer {
    private String firstName;
    private String lastName;
    private Account account;

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setAccount(Account account) {
        this.account = account;
    }

    public Account getAccount() {
        return account;
    }


}
package corm.atguigu01._this.exer3;

/**
 * ClassName:Bank
 * Package:corm.atguigu01._this.exer3
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/5 21:09
 * @Version 1.0
 */
public class Bank {
    private Customer[] customers;//用于保存多个客户
    private int numberOfCustomer;//用于记录存储的客户的个数

    public Bank() {
        this.customers = new Customer[10];
    }

    public void addCustomer(String f, String l) {
        Customer customer = new Customer(f, l);
        customers[numberOfCustomer] = customer;
        numberOfCustomer++;
    }

    public int getNumberOfCustomers() {
        return numberOfCustomer;
    }

    public Customer getCustomer(int index) {
        return customers[index];
    }
}

创建的对象:

package corm.atguigu01._this.exer3;

/**
 * ClassName:AccountCustomerTest
 * Package:corm.atguigu01._this.exer3
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/5 21:04
 * @Version 1.0
 */
public class BankTest {
    public static void main(String[] args) {
        Bank bank = new Bank();
        bank.addCustomer("妄","竹");
        bank.addCustomer("妄","汐霜");

        Account account = new Account(1000);
        account.deposit(100);
        bank.getCustomer(0).setAccount(account);

        Account account2 = new Account(80);
        bank.getCustomer(1).setAccount(account2);
        account2.withdraw(100);
    }
}

内存图:

面向对象特征二:继承

继承有延续,扩展的意思

superclass父类

subclass子类

角度一:从上至下:

说明:Student类继承了父类Person的所有属性和方法,并增加一个属性school。Person类中的属性和方法,Student类都可以使用

角度二:从下而上:

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类中无需在定义这些属性和行为,只需要和抽取出来的类构成继承关系。

继承的好处:

继承的出现减少了代码的冗余,提高了代码的复用性

继承的出现,更有利于功能的扩展

继承的出现让类与类之间出现了is-a的关系

不要为了获取其它类中某个功能就去继承,要看看是否符合伦理

继承的语法:

格式:

通过extends关键字,声明一个类继承另一个类

[修饰符] class 类a {

}

[修饰符] class 类b extends 类a{

}

举例:

person类:

package corm.atguigu03._extends;

/**
 * ClassName:Person
 * Package:corm.atguigu03._extends
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/7 17:08
 * @Version 1.0
 */
public class Person {
    String name;
    int age;

    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}

student类继承person类

package corm.atguigu03._extends;

/**
 * ClassName:Student
 * Package:corm.atguigu03._extends
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/7 17:10
 * @Version 1.0
 */
public class Student extends Person {
        String school;
        int id;
        public void study () {
            System.out.println("学习");
        }

        public static void main(String[] args) {
        Student student = new Student();
        student.name = "妄汐霜";
        student.age = 18;
        student.sleep();
        student.study();

    }


}

有了继承性以后,子类就获得了父类中声明的所有的属性和方法,但是由于封装性的影响,在子类里不能直接使用或者访问在父类中private修饰的属性或方法。

因为:

子类在继承父类以后,还可以扩展自己特有的功能(体现:增加特有的属性,方法)

不要为了继承而继承,在继承之前,要判断一下是否is-a的关系

默认的父类:

Java中声明的类,如果没有显示的声明其父类时,则默认继承于java.lang.Object

Java支持多层继承,且一个父类能有多个子类,但是一个子类不能有多个父类

举例1:

父类:

package corm.atguigu03._extends.exer1;

/**
 * ClassName:Mankind
 * Package:corm.atguigu03._extends.exer1
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/7 18:58
 * @Version 1.0
 */
public class Mankind {
    private int sex;
    private int salary;


    public int getSex() {
        return sex;
    }

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

    public int getSalary() {
        return salary;
    }

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

    public void manOrWoman() {
        if (sex == 1) {
            System.out.println("man!");
        } else {
            System.out.println("woman");
        }
    }

    public void employeed() {
        if (salary == 0) {
            System.out.println("no job");
        }else{
            System.out.println("job");
        }

    }


}

子类:

package corm.atguigu03._extends.exer1;

/**
 * ClassName:Kids
 * Package:corm.atguigu03._extends.exer1
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/7 19:02
 * @Version 1.0
 */
public class Kids extends Mankind {
    private int yearsOld;

    public int getYearsOld() {
        return yearsOld;
    }

    public void setYearsOld(int yearsOld) {
        this.yearsOld = yearsOld;
    }

    public void peintAge(){
        System.out.println(yearsOld);
    }

}

测试:

package corm.atguigu03._extends.exer1;

/**
 * ClassName:KidsTest
 * Package:corm.atguigu03._extends.exer1
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/7 19:03
 * @Version 1.0
 */
public class KidsTest {
    public static void main(String[] args) {
        Kids kid = new Kids();
        kid.setSex(1);
       kid.manOrWoman();
       kid.setSalary(400);
       kid.employeed();
       kid.setYearsOld(19);
       kid.peintAge();


    }
}

四种权限修饰符:

方法的重写:

1.为什么需要方法的重写?

子类在继承父类以后,就获取了父类中的所有方法,但是父类中的方法可能不适合子类,所以子类就要对父类中继承过来的方法进行覆盖,覆写的操作。

举例:

public class Account {
    double balance;//余额
    
    public void withdraw(double amount) {
        //取钱的操作
    }
}

class  extend extends Account {
    double protectedBy;//透支额度
    public void withdraw(double amount) {
        //判断余额是否足够取钱
        //如果不够就从透支额度里取
    }
    
    
}

这种子类的方法覆盖父类中的方法的行为就叫方法重写

2.什么是方法的重写?

子类对父类继承过来的方法进行覆盖,覆写的操作,就称为方法的重写

练习:

类:

package corm.atguigu04._override.exer1;

/**
 * ClassName:Person
 * Package:corm.atguigu04._override.exer1
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/8 16:49
 * @Version 1.0
 */
public class Person {

    public String name;
    public int age;

    public void eat() {
        System.out.println("吃饭");
    }

    public void sleep() {
        System.out.println("睡觉");
    }
}
package corm.atguigu04._override.exer1;

/**
 * ClassName:Student
 * Package:corm.atguigu04._override.exer1
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/8 16:49
 * @Version 1.0
 */
public class Student extends Person {
    String school;
    int id;

    public void study() {
        System.out.println("学习");
    }

    public void eat() {
        System.out.println("吃屎");
    }



}

创建的对象:

package corm.atguigu04._override.exer1;

/**
 * ClassName:StudnetTest
 * Package:corm.atguigu04._override.exer1
 * Description:
 *
 * @Author 妄汐霜
 * @Create 2025/11/8 16:56
 * @Version 1.0
 */
public class StudentTest {
    public static void main(String[] args) {
        Student student = new Student();

        student.sleep();
        student.eat();
    }
}

注意导包的路径是否正确

3.方法重写的规则:

1.父类被重写的方法与子类中重写的方法的方法名和形参列表必须相同

2.子类重写的方法的权限修饰符不小于父类中被重写方法的权限修饰符

特例:如果父类中的方法是private,子类不能重写父类中声明为private的方法

3.关于返回值类型

父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型必须是void

父类被重写的方法的返回值类型是基本数据类型,则子类重写的方法的返回值类型必须与被重写的方法的返回值类型相同

父类被重写的方法的返回值类型是引用数据类型(比如类),则子类重写的方法的返回值类型可以与被重写的方法的返回值类型相同,或是被重写方法的返回值的子类

4.子类重写的方法抛出的异常类型可以与父类被重写的方法抛出的异常类型相同,或是父类被重写的方法抛出的异常的子类

补充说明:方法体没有要求,但是子类重写的方法的方法体必然与父类被重写的方法不同

面试体:区分方法的重载与重写

重载:两同一不同

重写:继承以后,子类覆盖父类中同名同参数的方法

super关键字:

一.关键字的使用:

1.为什么需要super?

举例1:子类继承父类之后,对父类的方法进行重写,那么在子类中,如果还想调用父类的那个被重写的方法就需要super关键字。

举例2:子类继承父类之后,发现子类和父类中定义了同名的属性(属性没有重写之说,方法才有),如果要区分这个属性,就要用到super关键字。

2.super的理解、

父类的(属性,方法)

3.super可以调用的结构:

属性,方法,构造器

举例:

父类:

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

    public void eat() {
        System.out.println("吃饭");
    }

    public void sleep() {
        System.out.println("睡觉");
    }
}

子类:

public class Student  extends Person{
    String school;
    int id;

    public void study() {
        System.out.println("学习");
    }

    public void eat(){
        System.out.println("学生要多吃饭");
    }

    public void sleep(){
        System.out.println("学生要多睡觉");
    }

    public void show(){
        super.sleep();
    }


    }

子类测试:

public class Student  extends Person{
    String school;
    int id;

    public void study() {
        System.out.println("学习");
    }

    public void eat(){
        System.out.println("学生要多吃饭");
    }

    public void sleep(){
        System.out.println("学生要多睡觉");
    }

    public void show(){
        super.sleep();
    }


    }

3.1super调用属性,方法

子类继承父类之后,我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法。(满足封装性的前提下),调用时需要使用super关键字。

一般情况下,我们可以考虑省略“super.”的结构,但是,如果出现子类重写了父类的方法或子父类中出现了同名的属性时(不过实际开发中要避免这种情况的出现),则必须使用“super.”的声明,显示的调用父类被重写方法或父类中声明的同名的属性。

3.2super调用构造器

1.子类继承父类时,不会继承父类的构造器,只能通过“super(形参列表)”的方式调用父类指定的构造器。

2.规定:"super(形参列表)",必须声明在构造器首行

3.前面讲过,在构造器的首行可以使用“this(形参列表)”,调用本类中重载的构造器

结合2,结论:在构造器首行,“this(形参列表)”和“super(形参列表)”只能二选一。

4.如果在子类构造器的首行既没有显示调用“this(形参列表)”,也没有显式调用“super(形参列表)”,则子类此构造器默认调用父类中空参的构造器

5.由3和4得到结论:子类的任何一个构造器中,要么调用本类中重载的构造器,要么调用父类中的构造器。只能是这两种情况

6.由5得到:一个类中声明有n个构造器,最多有n-1个构造器中使用“this(形参列表)”,则剩下的那个一定使用“super(形参列表)”

总结:通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接的调用到父类的构造器。

举例:

父类:

public class Account {
    private String id;
    private double balance;
    private double annualInterestRate;


    public Account(String id, double balance, double annualInterestRate) {
        this.id = id;
        this.balance = balance;
        this.annualInterestRate = annualInterestRate;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public double getBalance() {
        return balance;
    }

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

    public double getAnnualInterestRate() {
        return annualInterestRate;
    }

    public void setAnnualInterestRate(double annualInterestRate) {
        this.annualInterestRate = annualInterestRate;
    }

    public Account() {
    }
    public void deposit(double amount) {
        balance += amount;
    }

    public void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
        }else{
            System.out.println("您的余额不足");
        }
    }
}

子类:

public class CheckAccount extends Account{
    private double overdraft;

    public CheckAccount(String id ,double balance,double annualInterestRate){
        super(id,balance,annualInterestRate);
    }
    public CheckAccount(String id,double balance,double annualInterestRate,double overdraft){
        super(id, balance, annualInterestRate);
        this.overdraft = overdraft;
    }

    public double getOverdraft() {
        return overdraft;
    }

    public void setOverdraft(double overdraft) {
        this.overdraft = overdraft;
    }

    public void withdraw(double amount){
        if(amount < getBalance()){
            super.withdraw(amount);
        }else if(getBalance() + overdraft > amount){
            overdraft -= amount - getBalance();
            super.withdraw(getBalance());
        }else{
            System.out.println("超过可透支限额");
        }
    }
}

测试:

public class CheckAccountTest {
    public static void main(String[] args) {
        CheckAccount account = new CheckAccount("1122",20000,0.045,5000);
        account.withdraw(5000);
        System.out.println("余额是:" + account.getBalance() + "可透支额度是:" + account.getOverdraft());
        account.withdraw(18000);
        System.out.println("余额是:" + account.getBalance() + "可透支额度是" + account.getOverdraft());
        account.withdraw(3000);
        System.out.println("余额是" + account.getBalance() +"可透支额度" + account.getOverdraft());
    }
}

子类对象实例化的全过程:

2.从过程的角度:

当我们通过子类的构造器创建对象时,子类的构造器一定会,一定会,一定会直接或者间接的调用其父类的构造器。而父类也会调用它的父类的构造器

在创建子类对象的过程中,一定会调用父类中的构造器

面向对象的特征之三:多态性

只有方法有多态,属性没有多态

代码举例:

父类:

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


    public void eat(){
        System.out.println("吃饭");
    }

    public void sleep(){
        System.out.println("睡觉");
    }

}

子类:

public class Man extends  Person {
    public void eat(){
        System.out.println("吃肉");
    }
    public void sleep(){
        System.out.println("男人睡觉");
    }
    public void getMoney(){
        System.out.println("男人挣钱");
    }


}
public class Woman extends Person{
    public void eat(){
        System.out.println("女人吃饭");
    }
    public void sleep(){
        System.out.println("女人睡觉");
    }
    public void spendMoney(){
        System.out.println("花钱");
    }
}

测试:

public class PersonTest {
    public static void main(String[] args) {
        Person p1 = new Man();
        Person p2 = new Woman();

        p1.eat();吃肉
        p2.eat();//女人吃饭
}

在编译器中,编译器看到的是左边的,以为创建的是Person类,但实际上创建的是Man类,调用方法也是调用的Man和Woman类

多态的使用:虚方法调用,编译看左边,运行看右边

5.多态性的适用性:只适用于方法,不适用于属性

属性的话最前面声明的是什么,就会调用哪里的

比如:

父类中的名字:

public class Person {
     String name = "妄竹";
     int age = 19;

子类中的名字:

public class Man extends  Person {
  
    String name = "妄汐霜";
    int age = 20;

测试:

Person p1 = new Man();
System.out.println(p1.name);//妄竹

6.多态的好处和弊端:

好处:极大的减少了代码的冗余,不需要定义多个重载的方法

弊端:在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但是由于声明为父类的引用,导致不能直接调用子类特有的属性和方法。

比如:

父类:

子类:

测试:/

最后如果要打印,打印出来的结果是dog类中eat和jump的方法,但是不能直接调用dog中的watchdoor方法

向下转型:

向下转型:使用强转符

public class PersonTest {
    public static void main(String[] args) {
        Person p1 = new Man();
        Person p2 = new Woman();

        p1.eat();//吃肉
        p2.eat();//女人吃饭
        System.out.println(p1.name);//妄竹
        //p1.getMoney();,不能直接调用子类中的方法

        //向下转型,使用强转符
        Man m1 = (Man)p1;
        Woman m2 = (Woman)p2;

        //此时就可以通过m1和m2调用Man和Woman中的扩展的方法
        m1.eat();//吃肉
        System.out.println(m1.name);//妄汐霜
        m1.getMoney();//这里可以直接调用子类中的方法
        m2.spendMoney();//花钱
        
    }
}

不过在向下转型之前,要先使用instanceof进行判断,避免出现类型转换异常

格式:a instanceof A : 判断对象a是否是类A的实例

if(p2 instanceof Man){
    Woman m2 =(Woman)p2;//然后通过m2就可以调用Woamn类里的扩展方法
    m2.spendMoney();
}
if(p1 instanceof Man){
    Man m1 = (Man)p1;
    m1.eat();
    System.out.println(m1.name);
    m1.getMoney();
}

练习1:

父类:

public class GeometricObject {
    protected  String color;
    protected double weight;

    protected GeometricObject() {
    }

    protected GeometricObject(String color, double weight) {
        this.color = color;
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double findArea() {
        return 0.0;
    }
    public double displayGeometricObject(GeometricObject g1){
        return 0.0;
    }

}

子类:

public class Circle extends GeometricObject{
    private double radius;


    public Circle() {
    }

    public Circle(double radius,String color,double weight) {
        super(color,weight);
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double findArea() {
        return Math.PI * radius * radius ;
    }

}
public class MyRectangle extends GeometricObject {
    private double width;
    private double height;

    public MyRectangle() {
    }

    public MyRectangle(String color, double weight, double width, double height) {
        super(color, weight);
        this.width = width;
        this.height = height;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double findArea() {
        return width * height;
    }
}

测试:

public class GeometricTest {
    public static void main(String[] args) {
         GeometricTest g1 = new GeometricTest();
         Circle c1 = new Circle(2.3,"red",1.0);
         Circle c2 = new Circle(3.4,"red",1.0);

        g1.displayGeometricObject(c1);
        g1.displayGeometricObject(c2);

        System.out.println(g1.equalsArea(c1, c2));
    }


    public boolean equalsArea(GeometricObject g1,GeometricObject g2){
        if(g1.findArea() == g2.findArea()){
            return true;
        }
        else{
            return false;
        }
    }

    public void  displayGeometricObject(GeometricObject g1){
        System.out.println(g1.findArea());
    }



}

练习2:

父类:

public class Graduate extends Student{
    public String major = "IT";

    @Override
    public String getInfo() {
        return super.getInfo()  + "major=" + major;
    }
}

子类:

public class Person {
    protected  String name = "person";
    protected int age =50;
    public String getInfo(){
        return "name = "+name+",age = "+age;
    }
}
public class Student extends  Person{
    protected String school = "pku";
    public String getInfo(){
        return super.getInfo() + " , school=" + school;
    }
}

测试:

public class InstanceTest {
    public void method(Person e){
        System.out.println(e.getInfo());
        if(e instanceof  Graduate){
            System.out.println("a graduate student\na studnet\na person");
        } else if (e instanceof  Student) {
            System.out.println("a Student\na Person");
        }else {
            System.out.println("a person");
        }
    }


    public static void main(String[] args) {
            InstanceTest test = new InstanceTest();
            test.method(new Student());
    }
}

练习3:

父类:

public class Person {
    public void eat(){
        System.out.println("吃饭");
    }
    public void toilet(){
        System.out.println("上厕所");
    }
}

子类:

public class Man extends Person {
     public void eat(){
            System.out.println("男人吃饭");
        }
     public void smoke(){
         System.out.println("抽烟");
     }


}
public class Woman extends Person{
    public void eat(){
        System.out.println("女人吃饭");
    }
    public void makeup(){
        System.out.println("化妆");
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        test.meeting(new Man(), new Woman(), new Man(), new Woman());
    }

    public static  void meeting(Person... ps) {
        for(int i = 0; i < ps.length; i++){
            ps[i].eat();
            ps[i].toilet();
            if(ps[i] instanceof Man){
                Man man = (Man)ps[i];
                man.smoke();
            }
            if(ps[i] instanceof Woman){
                Woman woman = (Woman)ps[i];
                 woman.makeup();
            }
        }
    }
}

面试题:

多态是编译时行为还是运行时行为?

答:运行时。编译时编译器看到的是左边的父类(编译看左边,运行看右边)

Object类以及clone(),finalize()的理解:

常用方法:

重点方法:equals()\toString()

了解方法:clone()\finalize()

Clone():

就是复制,复制完之后有两个对象,各自有一套属性,互不影响。

finalize():

直白一点就是,临死之前,你还有什么想做的,最后让你做掉。做完之后就回收。

此方法是自己调的,GC触发方法自己调用此方法

equals()的使用:

适用性:

任何引用数据类型都可以使用。

这俩地址不同

这俩地址不同,所以第一个输出是false

因为在String类中改写了equals()方法,所以调用的是String类中的equals()方法,第二个是true

jdk8中,String类的equals()方法:

alt+ins(选择重写方法,然后让IDEA自动重写)

高频面试题:区分 == 和equals()

不重写就是调用object类中的equals方法,如果重写就是调用重写后的方法

应用:

类:

public class Account {
    private double balance;

    public Account(){
    }

    public Account(double balance) {
        this.balance = balance;
    }

    public double getBalance() {
        return balance;
    }

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

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        Account account = (Account) o;
        return Double.compare(balance, account.balance) == 0;
    }


}
public class Customer {
    private String name;
    private int aga;
    private Account account;

    public Customer() {
    }

    public Customer(String name, int aga, Account account) {
        this.name = name;
        this.aga = aga;
        this.account = account;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        Customer customer = (Customer) o;
        return aga == customer.aga && Objects.equals(name, customer.name) && Objects.equals(account, customer.account);
    }


}

测试:

public class CustomerTest {
    public static void main(String[] args) {
        Customer cust1 = new Customer("tom",19,new Account(2000));
        Customer cust2 = new Customer("tom",19,new Account(2000));

        System.out.println(cust1.equals(cust2));//true


    }
}

注意:

toString()方法:

练习:

父类:

public class GeometricObject {
    protected String color = "white";
    protected double weight = 1.0;

    public GeometricObject() {
        color = "white";
        weight = 1.0;
    }

    public GeometricObject(String color, double weight) {
        this.color = color;
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
}

子类:

public class Circle  extends  GeometricObject{
    private double radius;

    public Circle() {
        color = "white";
        weight = 1.0;
        radius = 1.0;
    }

    public Circle(double radius) {
        color = "white";
        weight = 1.0;
        this.radius = radius;
    }

    public Circle(String color, double weight, double radius) {
        super(color, weight);
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }


    public double findArea() {
        return 3.14 * radius * radius * radius;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || getClass() != o.getClass()) return false;
        Circle circle = (Circle) o;
        return Double.compare(radius, circle.radius) == 0;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(radius);
    }


    @Override
    public String toString() {
        return "Circle{" +
                "radius=" + radius +
                '}';
    }
}

测试:

public class GeometricObject {
    protected String color = "white";
    protected double weight = 1.0;

    public GeometricObject() {
        color = "white";
        weight = 1.0;
    }

    public GeometricObject(String color, double weight) {
        this.color = color;
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }
}

真题:

构造器可不可以重写?

构造器不能重写,但构造器可以重载

你对多态怎么理解的?

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值