Java的Object类【tostring()方法和equals()方法】&&内部类

Object类

java.lang.Object类
类 Object 是类层结构的根类。每个类都是用Object作为超类。所有对象(包括数组)都实现这个类的方法。
该类实现了基本的实现方法,都可以继承进行调用。

tostring方法

person类默认继承了Object类,可以使用toString()方法,返回该对象的字符串表示。直接打印,其实就是调用了p.toString()方法。
作用:

  • 打印对象的信息
  • 重写之前:打印的是包名类名@地址值
  • 重写之后:打印的是对象中的属性值

Tostring的重写

  • 如果没有重写,打印的就是对象的地址值【默认】

  • 如果重写了,就按照重写的方式进行打印。

package cn.itcast.day02.dem01;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class objshow {
    public static void main(String[] args) {
     Person p=new Person("yjj",18);
     System.out.println(p);//cn.itcast.day02.dem01.Person@75412c2f
     String s=p.toString();
     System.out.println(s);//cn.itcast.day02.dem01.Person@75412c2f
       
        "未重写"
        Random r=new Random();
        System.out.println(r);//java.util.Random@13b6d03
        "重写"
        Scanner scan=new Scanner(System.in);
        System.out.println(scan);//java.util.Scanner[delimiters=\p{javaWhitespace}+][position=0][match vali
        "重写"
        ArrayList<Integer> list=new ArrayList<>();
        list.add(1);
        list.add(2);
        System.out.println(list);//[1, 2]
    }
}

tostring()具体的重写

package cn.itcast.day02.dem01;
import java.util.Objects;
public class Person {
    String name;
    int age;

    public Person() {
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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;
    }


}

equals方法

person类默认继承了Object类,可以使用equals()方法
boolean equals(Object obj)指示其他某个对象是否与此对象“相等”

  • 基本数据类型:比较的是值
  • 引用数据类型:比较的是两个对象的地址值
    比较两个地址值没有意义,需要对equals方法进行重写。

equals方法的重写
例如比较person两个对象的属性值(name,age)

  • 重写前:比较两个对象的地址值
  • 重写后:比较对象的属性值

相同,返回true;
不相同,返回false;
问题:隐含一个多态
object obj=p2=nwe Person (“古力娜扎”,18);
多态的弊端,无法使用子类特有的内容(属性,方法);
解决方案:可以使用向下转型把object类转换为Person类

   @Override
  public  boolean equals(Object obj) {
        //传递的obj是自己本身,提高效率
        if (obj == this) {
            return true;
        }
        //提高效率
        if (obj == null) {
            return false;
        }
        //是person的类型在转,防止类型转换异常;
        //getclass()!=o.getClass()使用反射技术,判断o是否Person类型 等价于
        if (obj instanceof Person) {
            Person p2 = (Person) obj;
            boolean b = this.name.equals(p2.name) && this.age == p2.age;
            return true;
        }
        return false;
    }
 Person p1=new Person("迪丽热巴",18);
        Person p2=new Person("迪丽热巴",18);
        boolean b=p1.equals(p2);
        System.out.println(p1);
        System.out.println(p2);
        System.out.println(b);
cn.itcast.day02.dem01.Person@50cbc42f
cn.itcast.day02.dem01.Person@75412c2f
true

objects类

equals()方法:比较两个对象是否相同,但是加了一些健壮性的判断

@Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
 String s1=null;
        String s2="abc";
        System.out.println(s1.equals(s2));//出现安全问题。出现空指针异常
        boolean r= Objects.equals(s1,s2);//未出现异常
        System.out.println(r);

内部类

如果一个事物事物内部包含另一个事物,那么这就是一个内部包含另一个类。
分类:
1.内部成员类
2.局部内部类(包含匿名内部类)
成员内部类的定义格式:
修饰符 class 外部类名称{
修饰符 class内部类名称{
//…
}
//…
}
注意:内用外,随意访问;外用内,需要内部类对象。
如何使用成员内部类?两种方式
1.

  • 间接方式:在外部类方法中,使用内部类,然后main只需要调用外部类的方法
  • 直接方式:公式
    类名称 对象名=new 类名称();
    【外部类名称.内部类名称 对象名=new 外部类名称().new 内部类名称();】
Body类
package cn.itcast.day02.dem01;
public class Body {//外部类
    public class heart{//成员内部类
        //内部类方法
        public void beat(){
            System.out.println("心脏跳动,砰砰砰");
            System.out.println(name);
        }

    }
    //外部类成员变量
    private String name;
    //外部类成员方法
    public void methodbody(){
        System.out.println("外部类方法");
        new heart().beat();

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
主函数:
package cn.itcast.day02.dem01;

public class Interdemo {
    public static void main(String[] args) {
        //通过外部对象,调用外部类方法里面间接使用内部类heart
        Body b=new Body();
        b.methodbody();
        //直接调用内部成员方法,创建内部对象
       Body.heart h=new Body().new heart();
       h.beat();

    }
}

如何访问外部类重名成员变量
外部类名称.this.外部类成员变量名

package cn.itcast.day02.dem01;

public class Outer {
    int num=10;
    public class inter{
        int num=20;
        public void intermethod(){
            int num=30;
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(Outer.this.num);
        }
    }
}
主函数
package cn.itcast.day02.dem01;
public class interdmain {
    public static void main(String[] args) {
        Outer.inter b=new  Outer().new inter();
        b.intermethod();
    }
}
运行结果
30
20
10

局部内部类

如果一个类定义在一个方法的内部,那么这就是局部内部类。
“局部”:只能当前所属的方法才可以使用它,出了这个方法外面就不能用了。
定义格式:

修饰符 class 外部类名称{
    修饰符 返回值类型 外部类方法名称(参数列表){
    class 局部内部类名称{
                 //......
       }
    }
}

注意事项
public>protected>(default)>private
定义一个类的时候,权限修饰符规则:

  1. 外部类:public / (default)
  2. 成员内部类:public/protected/(default)/private
  3. 局部内部类:什么都不能写

例子:

package cn.itcast.day02.dem01;
import java.security.PublicKey;
public class localOuter {//外部类
    public void methodouter(){//外部类成员方法
        class inter{//局部内部类
            int num=100;//局部内部类成员变量
            public  void methodinter(){//局部内部类成员方法
                System.out.println(num);
            }
        }
        inter in=new inter();
        in.methodinter();

    }
}
package cn.itcast.day02.dem01;
public class interdmain {
    public static void main(String[] args) {
        Outer.inter b=new  Outer().new inter();
        b.intermethod();
        localOuter o=new localOuter();
        o.methodouter();
    }
}

局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效的final的】
Java8,可以省略关键字final
原因:
new出来对象在堆里。
局部变量是跟着方法走的,在栈内存中。
方法运行结束后,立刻出栈,局部变量消失。
new出来的对象在堆里面持续存在,知道垃圾回收消失。
结局方法:final 关键字,类copy一份

package cn.itcast.day02.dem01;
import java.security.PublicKey;
public class localOuter {//外部类
    public void methodouter(){//外部类成员方法,生命周期短
    int num=200;
        class inter{//局部内部类,生命周期长,
            public  void methodinter(){//局部内部类成员方法
                System.out.println(num);//外部局部变量200
            }
        }
        inter in=new inter();
        in.methodinter();

    }
}

匿名内部类

如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,
那么这种情况下可以省略该类的定义,而改为使用【匿名内部类】。
匿名内部类的定义格式:
接口名称 对象名 =new 接口名称(){
//覆盖重写所有的抽象类
};

接口:
package cn.itcast.day02.dem01;
public interface Myinterface {
    public void method();
}
package cn.itcast.day02.dem01;
public class interfacedemo {
    public static void main(String[] args) {
  匿名内部类:
        Myinterface obj=new Myinterface() {
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了所有抽象方法的重载AAA");
            }

            @Override
            public void method2() {

            }
        };
        obj.method1();
        obj.method2();
        //有名字,使用多个方法
        //无名【匿名对象】,只能一个方法
         匿名内部类也是匿名对象:
      new Myinterface() {
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了所有抽象方法的重载BBB");
            }

            @Override
            public void method2() {

            }
        }.method1();

    }
}

注意事项
对格式“new 接口名称(){…}”进行解析
1.new 代表创建对象的动作
2.接口名称就是匿名内部类需要实现哪个接口
3.{…}匿名内部类的内容
4.匿名内部类,在【创建的对象】中,只能使用一次。
如果希望多次创建对象,而且内容一样的话,那么就必须使用单独定义的实现类或者写多遍。
5.匿名对象,在调用方法的时候,只能调用唯一一次。
如果希望同于一个对象,调用多次方法,那么必须给对象取个名字。
6. 匿名内部类是省略了【实现类/子类】,但是匿名对象省略了【对象名称】
接口和类作为成员变量使用

武器类
package cn.itcast.day02.dem01;
public class Weapon {
    private String code;

    public Weapon(String code) {
        this.code = code;
    }

    public Weapon() {
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}
Skill接口
package cn.itcast.day02.dem01;
public interface  Skill {
    public void use();
}
实现接口的实现类
package cn.itcast.day02.dem01;
public class skillImpl implements Skill {
    @Override
    public void use() {
        System.out.println("bababababa");
    }
}

英雄类:使用接口成员变量和类成员变量
package cn.itcast.day02.dem01;
public class Hero {
    private String name;
    private int age;
    private Weapon w;//类
    private Skill s;//接口
public void attack(){

    System.out.println("我叫"+name+"年龄是"+age+"使用武器为"+w.getCode());
  s.use();//调用抽象接口里的方法
    System.out.println("释放技能完毕");
}
    public Hero() {
    }

    public Hero(String name, int age, Weapon w, Skill s) {
        this.name = name;
        this.age = age;
        this.w = w;
        this.s = s;
    }

    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 Weapon getW() {
        return w;
    }

    public void setW(Weapon w) {
        this.w = w;
    }

    public Skill getS() {
        return s;
    }

    public void setS(Skill s) {
        this.s = s;
    }
}
三种实现方法:
package cn.itcast.day02.dem01;
public class heroMain {
    public static void main(String[] args) {
        Hero h=new Hero();
        h.setAge(18);
        h.setName("妲己");
        Weapon w=new Weapon("昆仑剑");
        h.setW(w);
        skillImpl s=new skillImpl();
        h.setS(s);
        h.attack();
        //匿名内部类
        Skill s2=new Skill() {
            @Override
            public void use() {
                System.out.println("biubiubiu");
            }
        };
        h.setS(s2);
        h.attack();
        //匿名内部类和匿名内部对象
       h.setS(new Skill() {
           @Override
           public void use() {
               System.out.println("biu?=====biubiu");
           }
       });
        h.attack();
    }
}

我叫妲己年龄是18使用武器为昆仑剑
bababababa
释放技能完毕
我叫妲己年龄是18使用武器为昆仑剑
biubiubiu
释放技能完毕
我叫妲己年龄是18使用武器为昆仑剑
biu?=====biubiu
释放技能完毕

接口作为方法的参数和返回值

ackage cn.itcast.day02.dem01;

import java.util.ArrayList;
import java.util.List;

public class interfacedem {
    public static void main(String[] args) {
        //左边接口名称,右面是实现类名称,多态
        List<String> list=new ArrayList<>();
        List<String> r=addnames(list);
        for (int i = 0; i < list.size(); i++) {
           System.out.println(list.get(i));
        }

    }
    public static List<String> addnames(List<String> list){

        list.add("yjj");
        list.add("gnn");
        return list;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值