【Java进阶篇】第一章 面向对象(下篇)

发布于:2022-11-09 ⋅ 阅读:(6) ⋅ 点赞:(0) ⋅ 评论:(0)

🍁【Java进阶篇】第一章 面向对象(上篇)


5、访问控制权限

  • private 私有的

  • 啥也不写

  • protected 受保护的

  • public 公开的

public > protected > 默认 > private

访问控制权限修饰符 本类 同包 子类 任意位置
public
protected ×
默认 × ×
private × × ×

修饰符可修饰:

  • 属性:四个都能用
  • 方法:四个都能用
  • 类:只有public和默认可用,其余不行
  • 接口:只有public和默认可用,其余不行

6、Object类及其方法

在这里插入图片描述

toString()方法

作用:

把一个Java对象转化成字符串,子类应重写toString()为一个更简单易读的信息

源码:

public String toString(){
	return getClass().getName()+"@"+Integer.toHexString(hashcode());
}

在这里插入图片描述
输出引用的时候,会自动调用该引用的toString()方法。


equals方法

作用:

判断两个对象是否相等(注意判断两个基本数据类型是否相等直接用 ==)

源码:

public boolean equals(Object obj){
	return(this == obj);
}
//需要重写

在这里插入图片描述
判断两个Java对象(引用)是否相等,不用==,因为==比较的是对象的内存地址,而我们要比较的是Java对象的内容是否相等,故Object类中的equals方法需要重写。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public class MyTime {
    int year;
    int month;
    int day;

    public MyTime() {
    }

    public MyTime(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public boolean equals(Object obj){
        if (obj == null){
            return false;
        }
        if (!(obj instanceof MyTime)){
            return false;
        }
        if (this == obj){
            return true;
        }
        //能到这儿说明,不是null,而且是MyTime类型
        MyTime myTime = (MyTime)obj;
        /**
         *  if (this.year == myTime.year && this.month == myTime.month && this.day == myTime.day){
         *      return true;
         *   }
         *   return false;
         *   这三行直接合并为下面的return语句
         */

          return(this.year == myTime.year && this.month == myTime.month && this.day == myTime.day);


    }

}
class Test3{
    public static void main(String[] args) {
        MyTime myTime1 = new MyTime(2022,11,8);
        MyTime myTime2 = new MyTime(2022,11,8);
        System.out.println(myTime1.equals(myTime2));//true
    }
}

贴个IDEA直接Alt+Insert的:

@java.lang.Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof MyTime)) return false;
        MyTime myTime = (MyTime) o;
        return year == myTime.year && month == myTime.month && day == myTime.day;
    }

String类已经重写了toString()方法和equals()方法

/**
 * 验证String类已经重写了equals和toString()方法
 */
public class StringTest {
    public static void main(String[] args) {
        //通常创建字符串
        String s1 = "hello";
        String s2 = "abc";
        //String做为一个类,有自己的构造方法,也可这样创建字符串对象
        String s3 = new String("test1");
        String s4 = new String("test1");
        System.out.println(s3 == s4); //false
        System.out.println(s3.equals(s4));//true
        System.out.println(s3.toString());//test1
    }
}

在这里插入图片描述
Java中,基本数据类型的比较用==,引用数据类型用equals来判断

//若String是这样创建的,则==可以判断
String s1 = "qwe";
String s2 = "qwe";
System.out.println(s1 == s2); //true 

//但当String是new出来的,则不能再用==
String s1 = new String("ab");
String s2 = new String("ab");
System.out.println(s1 == s2); //false

所以,String的比较直接用equals()

当属性是引用数据类型时,equals()方法重写的最后一个if分支要用equals来判断,举例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

finalize方法

源码:

protected void finalize() throws Throwable{}
  • finalize方法的方法体中没代码
  • JVM的垃圾回收器负责调用这个方法
  • finalize()方法的执行时机:当一个Java对象即将被垃圾回收器回收的时候
  • 是一个时机,垃圾销毁时机,如果希望对象销毁时执行一段代码的话,则写到finalize()方法体中,类比人离世前做点啥
  • finalize()方法只需要重写,自会有GC机制来调用它

效果演示:

public class GCtest {
    public static void main(String[] args) {
        Person_ p = new Person_();
        p = null;
        //建议启动垃圾回收器
        //注意也不是100%命令启动
        System.gc();
    }
}
class Person_{
    //重写finalize()
    @java.lang.Override
    protected void finalize() throws Throwable{
        System.out.println(this + "将被销毁");
    }
}

运行效果:
在这里插入图片描述

在这里插入图片描述

hashCode()方法:

源码:

public native int hashCode();
//注意并不是抽象方法,属于底层调用C++程序

作用:
hashCode()方法返回的是哈希码,即一个Java对象的内存地址经过哈希算法得到的值

举例:

public class Test {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.hashCode());
    }
}

在这里插入图片描述

在这里插入图片描述

7、内部类

内部类即在类的内部又定义了一个新的类。分为:

  • 静态内部类:类似于静态变量
  • 实例内部类:类似于实例变量
  • 局部内部类:类似于局部变量,局部类中有一种类没有名字,成为匿名内部类

使用内部类,会让代码的可读性变差

class Test6{
    //静态内部类
    static class Inner1{
        
    }
    //实例内部类
    class Inner2{
        
    }
    public void doSome(){
        int i = 1;
        //局部内部类
        class Inner3{
            
        }
    }
}

在这里插入图片描述
在这里插入图片描述
匿名内部类的缺点:

一个类没有名字,没办法重复使用,且代码乱、可读性差