java中Object类、内部类、类与类之间的关系

Object类是java中的根类(祖类);

  • 所以的类都会继承Object类,空类也会继承;
  • 因此Object中的方法是所有类都能有的功能;
  • Object xxx = new xxx(); Object是可以发生多态的;
  • 由于可以发生多态,如果一个方法需要传递数据,我们不确定数据类型时,可以写Object;
  • 如何学习一个方法?
  •  1.该方法是谁的?
    
  •  2.是什么方法?(成员还是静态)
    
  •  3.方法的功能是什么?入参出参是什么?能实现什么,我们需要给它什么,它能给我们提供什么;
    
  •  4.方法的覆写,什么情况下覆写?
    
  • equals的设计目的是比较两个对象是否相等;
  • 但是它没有实现该功能,需要我们根据自己的需求进行覆写;
  • 两个对象可以是任何东西,只有具体到实例上,我们通过覆写才能实现这个方法;
  • @author MARECLE_YING
  • @Date 2021年1月18日
    */
    public class _02Equals {
    //main方法
    public static void main (String[]args){
    // 创建对象s1,s2;
    // 通过有参构造赋值给其赋值
    Student s1 = new Student(18,“李阳”);
    Student s2 = new Student(19,“李阳”);
    // 输出比较 ==比较的是内存地址 false
    System.out.println(s1 == s2);
    // equals 比较两个对象
    System.out.println(s1.equals(s2));
    }
    }
    // 创建学生类
    class Student{
    // 因为要使用getter/setter方法 所以要私有化成员变量
    private int age;
    private String name;
    // 使用getter/setter方法
    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 Student(int age, String name) {
    super();
    this.age = age;
    this.name = name;
    }
    // 创建无参构造
    public Student() {
    super();
    // TODO Auto-generated constructor stub
    }
    // 根据需求覆写 equals 方法
    // 需求 name相同就是一个学生
    @Override
    public boolean equals(Object arg0) {
    // 1.比较地址;地址相等说明是同一个对象,值也一定相等
    if(this == arg0){
    return true;
    }
    //2.判断对象的类型是否为当前类类型,否则返回false,不同的类没有可比性;
    if(arg0 instanceof Student){
    // 3. 强制类型转换,比较想要的数据
    Student s2 = (Student)arg0;
    //判断值是否相等
    // if (name.equals(s2.name) && age == s2.age){
    if (name.equals(s2.name)){
    return true;
    }
    }
    return false;
    }

}

equals

  • 设计目的:比较两个对象是否相等;
  • == 和 != :比较基本数据类型,比较值的大小;
  •  					比较引用数据类型,比较内存地址;
    
  • equals默认比较内存地址;
  •  		   实际中我们常常比较的都是对象的有意义的属性;
    
  • 比较字符串是否相等,应该用equals,因为 = = 比较的是内存地址;
  • 在String类中覆写了equals方法,比较的是值,而不是内存地址;
  • 所以我们同样也可以通过覆写,将同类的两个对象的属性,用equals去比较;
  • 不同类的对象,不具备可比性;
  • 实现方式:任何的引用类型比较,都必须转换为基本类型进行比较;除非就是想比较两个地址是否相同;
  • 面向对象就是一种基本数据封装的形式,所以我们比较的时候都要转换为基本类型比较;
  • @author MARECLE_YING
  • @Date 2021年1月18日
    /
    public class _01Equals {
    // main方法
    public static void main(String[]args){
    // 创建两个String类型的对象 s1 s2 s3
    String s1 = new String(“998”);
    String s2 = new String(“1088”);
    String s3 = new String(“1088”);
    //输出比较结果,比较的是内存地址,地址肯定是不同的;false
    System.out.println(s1 == s2);
    // equals 比较的是值的大小
    // 语法结构:对象1.equals(对象2)
    // 值不同,false
    System.out.println(s1.equals(s2));
    // 值相同,true
    System.out.println(s2.equals(s3));
    }
    }
    package _16_Object_Finalize;
    /
    *

finalize 方法功能

  • 垃圾在回收的最后一步调用该方法,想要实现什么覆写Object;
  • ①finalize是每个对象都有的方法,因为他们最终都会成为垃圾并被回收;
  • ②不需要程序猿调用,系统自动调用
  • ③ 什么是垃圾?在java中,如果没有更多的引用指向这个对象,那么这个对象就没有存在价值,系统会将其视为垃圾数据;
  • 等待被回收,回收之前,自动调用finalize方法
  • ④值得注意的是 finalize 与垃圾回收被没有关系,只是它的执行实际被设定在垃圾回收的最后一步这里,本身就相当于一个在这个时间点自动执行的成员方法;
  • ⑤一般用作一些对象回收前的数据销毁操作(应用场景)
  • @author MARECLE_YING
  • @Date 2021年1月18日
    /
    public class _01Finalize {
    //main方法
    public static void main(String[]args){
    // 实例化对象
    Animal animal = new Animal();
    // 将animal的地址设为空值
    animal = null;
    // 程序员建议垃圾回收器回收 jvm回收垃圾
    // 建议回收,可能存在不回收的情况
    System.gc();
    // 当垃圾过多的时候,不需要建议,系统自动回收
    // 使用for循环 创建999999个对象
    for(int i = 0 ; i<999999; i++){
    new Animal();
    }
    }
    }
    // 创建Animal类
    class Animal{
    // 创建一个finalize方法
    // 这个地方仅仅是通过finalize方法 向我们展示出了垃圾是否被回收
    // 实际上垃圾的回收与这个方法无关,回收的触发条件是对象,对象多了系统自动回收
    public void finalize(){
    System.out.println(this+“我要被回收了,救救我_”);
    }
    }
    package _16_Object_HashCode;
    /
    *

hashCode

设计目的:给每一个对象生成唯一的标志符
*

  • hash 哈希;同一个对象生成多次hash值,值一定相同;
  •  				多个对象生成多个hash值时,值可能会相同,不能确保生成的hash值不同,这种情况被称作哈希冲突;
    
  • 既然存在哈希冲突,所以哈希值就不能保证数据的唯一性;
  • 为了保证数据的唯一性,我们先比较哈希;
  • 哈希不同,说明对象不同;
  • 哈希相同,说明对象可能相同,所以我们需要再比较对象是否相同(equals)
  • 覆写hashCode时,还需要考虑什么?equals
  • 覆写equals时,同样也要考虑hashCode;
  • 所以java中是通过hashCode和equals来表示对象的唯一性的
  • hash算法:一种安全的加密算法,把不定长的值转换为定长的值;缺点是存在哈希冲突;
  • @author MARECLE_YING
  • @Date 2021年1月18日
    */
    public class _01HashCode {
    //main方法
    public static void main (String[]args){
    // 实例化对象
    _01HashCode hc = new _01HashCode();
    // 定义成员变量 并将对象hc的哈希值赋给它
    int hash = hc.hashCode();
    // 系统System 就是java的JVM虚拟机
    // 输出 hash的值 这个值应该是hc的哈希值 内存地址
    // 10进制的内存地址
    System.out.println(hash);
    // 输出 hc 的内存地址
    System.out.println(hc);
    // 输出 成员变量hash的值,将其转换为16进制输出
    System.out.println(Integer.toHexString(hash));
    }
    // 对hashCode覆写
    // 这里返回值 可以对hashCode的值更改
    @Override
    public int hashCode() {
    // TODO Auto-generated method stub
    // return super.hashCode();
    return 1999;
    }

}

toString:

  • 设计目的:返回该对象的字符串表示形式,可以通过这个方法,把每个对象的数据展示出来
  • 输出引用类型的时候,会自动调用该对象的toString方法;
  • @author MARECLE_YING
  • @Date 2021年1月18日
    */
    public class _01toString {
    public static void main(String[]args){
    // 实例化对象 s1 赋值 字符串
    String s1 = new String(“字符串”);
    // 为什么不是内存地址(因为String类中覆写了toString)
    System.out.println(s1);
    // 实例化对象 p1 并通过有参构造赋值
    Person p1 = new Person(18,“李阳”);
    // 输出的为p1 的地址
    System.out.println(p1);
    // 输出 姓名:李阳;年龄:18
    // 可以通过覆写toString 优化输出
    System.out.println(“姓名:”+p1.getName()+";年龄:"+p1.getAge());
    }
    }
    // 创建类
    class Person{
    // 私有化对象 使用getter/setter语句 对值进行操作
    private int age;
    private String name;
    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 Person(int age, String name) {
    super();
    this.age = age;
    this.name = name;
    }
    //覆写toString 优化输出
    @Override
    public String toString() {
    // TODO Auto-generated method stub
    //return super.toString();
    return “姓名:”+name+";年龄:"+age;
    }

}

内部类

  • 简单来讲就是在一个类体内创建一个新类;
  • ①成员内部类(非static)
  • ②静态成员内部类
  • ③局部内部类
  • ④匿名内部类(形参与实参)
  • 应用场景:当一个事物的内部某部分需要一个完整的结构进行描述,可以创建内部类;
  •  			  java中 允许一个类定义在一个类的内部,前者称为内部类,后者成为外部类;
    
  •  			  外部类调用内部类是,必须给出完整的名称让系统找到它;
    
  • 内部类的特性:可以访问外部类的私有化数据;
  • 变量:
  •  成员变量:成员内部类;
    
  •  静态变量:静态内部类;
    
  •  局部变量:局部内部类;
    
  •  形参与实参变量:匿名内部类;
    

成员内部类:

  •  1.可以等同看作成员变量
    
  •  2.成员内部类中不能有静态声明
    
  •  3.成员内部类中可以直接访问外部类所有的属性
    
  • @author MARECLE_YING

  • @Date 2021年1月18日
    */
    public class _01_InnerClass {
    // 私有化成员变量
    // 静态的
    private static String s1 = “A”;
    // 非静态的
    private String s2 = “B”;

     // 创建内部类
     // private public protected 都可以使用
     // 编译后的类名为 外部类类名$内部类类名
     // _01_InnerClass$_01_InnerClass
     	public class InnerClass{
     		//内部类不能有静态声明(静态类和静态方法)
     		//static int x;
     		// public static void m1(){}
     		public void m1(){
     			// 内部类可以直接访问外部类的所有属性
     			System.out.println(s1);
     			System.out.println(s2);
     	}
     }
     // main方法
     public static void main (String[]args){
     	//创建外部类对象
     	_01_InnerClass wb = new _01_InnerClass();
     	//通过外部类去创建内部类对象
     	InnerClass nb = wb.new InnerClass();
     	nb.m1();
     }
    

}
package _18_InnerClass;
/**

  • 静态内部类

  • 1.可以看作是静态变量
  • 2.静态内部类中,不能直接访问成员数据,需要有对象才行
  • 3.静态内部类中可以声明任何变量
  • @author MARECLE_YING
  • @Date 2021年1月18日
    */
    public class _02_InnerClass {
    //创建私有化变量
    // 静态的
    private static String s1 = “我是静态成员变量”;
    // 非静态的
    private String s2 = “我是成员变量”;
    // 创建静态内部类 static 声明静态的
    private static class InnerClass{
    // 创建m1静态方法
    public static void m1(){
    // 可以直接访问静态成员属性
    System.out.println(s1);
    // 不能直接访问成员属性
    // System.out.println(s2);
    // 需要用对象调用
    // 在类中创建一个对象 类相对于一个类型 对象s 相当于它的值
    _02_InnerClass s = new _02_InnerClass();
    // 用对象去调用输出
    System.out.println(s.s2);
    }
    // 不能直接访问成员属性
    public void m2(){
    // 不能直接访问成员属性,与方法是不是静态无关;
    // System.out.println(s2);
    System.out.println(“我是m2成员方法”);
    }
    }
    // 编写main方法
    public static void main(String[]args){
    // 全路径:外部类.内部类.静态
    _02_InnerClass.InnerClass.m1();
    // 访问当前类的静态属性的时候,类名可以省略(外部类的)
    // m1 是个静态的方法
    InnerClass.m1();
    // 对内部类实例化对象
    InnerClass x = new _02_InnerClass.InnerClass();
    // 同样的在当前类中,静态的可以省略外部类
    InnerClass x1 = new InnerClass();
    // 使用内部类对象 去调用自身的成员方法
    x1.m2();
    }
    }

类与类之间的关系:

  • ①继承关系/泛化关系;
  • ②实现关系;类与接口多实现;
  • ③依赖关系;在一个方法中调用另一个类;
  • ④关联关系;一个类的成员变量是另一个类对象的引用;
  • ⑤聚合关系;每个成员独自有能力,聚合在一起成为组织做大事,脱离组织也能自己成事;
  • ⑥组合关系;部分构成一个组合,成为一个整体;对于部分来讲,脱离整体一无是处,倘若整体衰亡,部分也跟着死去;
  • @author MARECLE_YING
  • @Date 2021年1月18日
    */
    public class _01ClassRelation {
    // 关联关系 一个类的成员变量是另一个类对象的引用;
    // 关联关系发生在类体中
    // 只要成员变量的类型不是基本数据类型,那么就是关联关系
    // A虽然是个类 但是在这里它相对于类型A 它的值是 a这个对象
    A a = new A();
    public static void main (String[]args){
    // 依赖关系 在一个方法中调用另一个类
    // 等同于局部变量是另一个类对象的引用
    // 依赖关系发生在方法体中
    // 在main方法中 调用另一个类
    A a2 = new A();
    }
    }
    //创建类
    class A{

}
// 继承关系 子类B继承父类A 类与类的继承是单继承
class B extends A{

}
// 创建接口
interface C{

}
interface D{

}
// 接口之间是多继承,逗号隔开
interface E extends C,D{

扫描二维码关注公众号,回复: 12264097 查看本文章

}
// 实现关系 类和接口 多实现
class F implements C,D{

}

猜你喜欢

转载自blog.csdn.net/MIRACLE_Ying/article/details/112797886