4.9 多态(向下转型)抽象 接口 Object(toString(),equals(),finalize())

1.多态向下转型

        多态中转型如果不对则报错ClassCaseException

public class Test{
    public static void main(String[] args){
         //向上转型
         Animal animal = new Cat();
         //向下转型(必须先向上转完才能向下转型)
         Cat cat = (Animal) animal;       
        //多态中常用instanceof来判断对象是否由某个类实例化而来
        //if(animal instanceof Cat/Animal){
        // Cat cat = (Animal) animal;     
        //}
    }
}
//父类
class Animal{
    
}    
//子类
class Cat extends Animal{

}

隐式多态:

        父类中子类调用方法或属性

        

public class Poly_02 {
    public static void main(String[] args) {
    Sub sub = new Sub();
    // System.out.println(sub.i);
    sub.m1();
    // sub.m2();
    }
}

class Sup {
    int i = 2;
    public void m1() {
    /**
     * this : 保存了当前对象的内存地址,是对象中第一个成员变量
     * 当前类 有是什么 : 指的是this出现在哪个类中,当前类就是哪个类
     * this的类型 是什么 才能保存当前类的对象
     * 可以保存当前类对象的类型,只有当前类类型和其父类类型
     * 如果是父类类型的话,就会发生多态,会丢失子类特有的属性 
     * 由于this可以调用所有属性,所以this一定是当前类类型, 也就是 Sup
     * Sup this;
     * this 出现在成员方法中,谁调用这个方法,this就保存谁的地址
     * 最终通过sub对象调用(继承) , 所以 this就指向sub对象
     * Sup this = sub;
     */
    System.out.println(this.i);
    System.out.println(i);
    this.m2();
    m2();
    }

    public void m2() {
    System.out.println("父类m2");
    }
}

class Sub extends Sup {
    int i = 22;

    public void m2() {
    System.out.println("子类m2");
    }
}

2.抽象

        抽象类不能被new创建对象,但可以被继承(因为可以被继承所以抽象类中有构造方法),抽象类修饰符为abstract,抽象方法(一般没有实现方法体,放在子类中去实现)必须放在抽象类中,但抽象类中可以有普通方法,继承抽象类必须重写所有抽象方法。

abstract class Animal {
    // 抽象方法,没有方法体
    public abstract void eat();
}

// 猫类
class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

// 狗类
class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }
}

3.接口

接口定义使用interface关键词(不能被new创建对象,没有构造器),1.8之前接口中只有抽象方法和常量,1.8及之后接口增加静态方法和成员方法功能。接口解决Java的单继承问题,利用implements去实现接口。接口中没有变量,只有常量用public static final(可省略)修饰

interface Animal {
    // 抽象方法,没有方法体
    public abstract void eat();
}

// 猫类
class Cat extends Object implements Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

// 狗类
class Dog implements Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }
}

接口和抽象类的区别:能同时使用时优先选择接口,接口能多实现,类只能单继承

4.toString()

Object中的toString()通常输出的是内存地址,当使用时不方便,通常会重写toString()输出需要的值

public class ToString01 {
    public static void main(String[] args) {
        User u1 = new User("admin", "root");
        System.out.println(u1);
    }
}

class User {
	public String toString() {
		return "我的用户名是 : "+username+"  , 我的密码是 : "+password;
	}

    private String username;
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }

    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }

    public User() {
        super();
    }
}

5.equals()

object中的equals()实现是利用==

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
}

==:基本类型比较的是值,应用类型比较的是地址(我们通常需要比较引用类型的内容,因此需要重写equals())

public class Equels01 {
    public static void main(String[] args) {
        Student s1 = new Student(1001, "张三", 18);
        Student s2 = new Student(1001, "张三", 18);
        System.out.println(s1 == s2);
        System.out.println(s1.equals(s2));
    }
}    

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
     // 判断要比较的对象,是否是当前类对象
    if (obj instanceof Student) {
        Student s1 = (Student) obj;
        if (s1.id == this.id  && this.name.equals(s1.name)) {
            return true;
        }
    }
    return false;
}

6.Finalize

// 当一个垃圾被回收的时候,会在回收前自动调用该对象的finalize方法,进行收尾工作
// 一般做一些关闭资源等操作
// 垃圾:当一个对象,没有任何引用指向他的时候,该对象被视为垃圾数据,等待垃圾回收器回收
// 如果我们手动调用finalize方法,那么只是一个方法调用而已,并不会回收
// finalize方法并没有回收垃圾的功能,只是在回收前,会自动调用执行而已
public class Fianlize {
    public static void main(String[] args) {
        Fianlize f = new Fianlize();
        f = null;
        // 程序员可建议垃圾回收器进行回收
        // for (int i = 0; i < 100000; i++) {
        // System.gc();
        // }
        // 垃圾比较多的时候,也会触发自动回收
        for (int i = 0; i < 10000000; i++) {
            new Fianlize();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println(this + " : 我要被回收了");
    }
}

  • 17
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值