Java学习日志Day15_匿名内部类_:API学习:object类

一、匿名内部类

  1. 什么是匿名内部类
    匿名内部类经常就是在局部位置使用!

     格式:
    	new 类名或者接口名(){
        重写抽象方法(){
            ...
        }
    } ;
    
  2. 匿名内部类的本质是什么?
    匿名内部类的本质就是继承了该抽象类或者实现了该接口的子类对象!

举例:
//定义一个接口
interface Inter{
    //目前接口中一个抽象方法
    //public abstract void show() ;

    //如果接口中有多个抽象方法
    void show() ;
    void show2() ;
}

//Demo类
class Demo{

    //定义一个方法
    public void method(){
        /*
            匿名内部类的格式
        new 类名或者接口名(){
               重写抽象方法(){
                   ...
               }
           } ;*/
       /* new Inter(){

            @Override
            public void show() {
                System.out.println("show Inter...");
            }
        }.show(); */


       //接口的匿名内部类重写接口中多个抽象方法
       /* new Inter(){

            @Override
            public void show() {
                System.out.println("show Inter...");
            }

            @Override
            public void show2() {
                System.out.println("show2 Inter...");
            }
        }.show() ;

        new Inter(){

            @Override
            public void show() {
                System.out.println("show Inter...");
            }

            @Override
            public void show2() {
                System.out.println("show2 Inter...");
            }
        }.show2() ;*/

       //优化
        Inter i = new Inter(){

            @Override
            public void show() {
                System.out.println("show Inter...");
            }
            @Override
            public void show2() {
                System.out.println("show Inter2...");
            }
        } ;

        i.show() ;
        i.show2() ;
    }
}

//测试类
public class NoNameClassDemo {

    public static void main(String[] args) {
        //创建Demo类对象
        Demo d = new Demo() ;
        d.method();
    }
}
  1. 匿名内部类在开发中的使用:
    方法的形式参数是类(具体类/抽象类),接口
举例:
//抽象的人类
abstract  class Person{
    public abstract  void work() ;
}
//定义PersonDemo类
class  PersonDemo{
    public void method(Person p){//抽象类,需要抽象类的子类对象
        p.work();
    }
}
//定义一个子类
class Worker extends  Person{

    @Override
    public void work() {
        System.out.println("工人日日夜夜的coding...");
    }
}

//测试类
public class PersonTest {

    public static void main(String[] args) {
        //需求:访问PersonDemo类中的method方法
        PersonDemo pd = new PersonDemo() ;
        //创建Person类对象---通过子类实例化
        Person p = new Worker();
        pd.method(p);

        System.out.println("-----------------------");

        //方式2:抽象类的匿名内部类
        //需求:访问PersonDemo类中的method方法
        PersonDemo pd2 = new PersonDemo() ;
        /*
        * 匿名内部类的格式:
        *   new 类名 或者接口名(){
        *           重写方法
        *   } ;
        * 匿名内部类的本质是:继承了该抽象类的或者是实现了该接口的子类对象!
        * */
        pd2.method(new Person(){

            @Override
            public void work() {
                System.out.println("工人日日夜夜的coding...");
            }
        });
    }
}

方法的形式参数是接口类型,需要接口的子实现类对象!
也可以使用的接口匿名内部类!

举例:
interface  Love{
    public abstract void love() ;
}

class LoveDemo{
    public void function(Love love){
        love.love();
    }
}
//定义接口的子实现类
class LoveImpl implements  Love{

    @Override
    public void love() {
        System.out.println("love Java!!!");
    }
}

//测试类中
public class Test2 {
    public static void main(String[] args) {
        //要访问LoveDemo类中的function方法
        //匿名内部类的使用
        LoveDemo ld = new LoveDemo() ;
        /*
         * 匿名内部类的格式:
         *   new 类名 或者接口名(){
         *           重写方法
         *   } ;
         * 匿名内部类的本质是:继承了该抽象类的或者是实现了该接口的子类对象!
         * */
        ld.function(new Love(){

            @Override
            public void love() {
                System.out.println("love javaee...");
            }
        });
        System.out.println("-----------------------------");

        //要访问LoveDemo类中的function方法
        LoveDemo ld2 = new LoveDemo() ;
        Love love = new LoveImpl() ;//接口多态
        ld2.function(love);
    }
}
练习:
补全代码 完成下面程序, 最终输出"helloworld"
   考点:
        静态方法 类名.方法名();
       匿名内部类的本质:继承了该抽象类或者是实现该接口的子类对象!
 
interface  Inter{
    void show() ;
}
class Outer{
    //补全代码
    public static Inter method(){
        return new Inter(){

            @Override
            public void show() {
                System.out.println("helloworld");
            }
        } ;
    }
}
public class InnerTest {
    public static void main(String[] args) {
        Outer.method().show() ;

        //第20行代码:
        //Outer.method()----->是一个静态方法,
        //Outer.method() .show() ;----> .show()---Outer.method()---->接口的子实现类对象!
    }
}

方法的返回值:引用类型 :抽象类/接口
如果是抽象类,那么返回该抽象类的子类对象

举例:
abstract class Person{
    public  abstract void study() ;
}
class StudentDemo{
    public Person method(){

        //Person是一个抽象类
        //Person p = new Student() ; //抽象类多态:给出了具体的子类
       // return p ;

        //不定义具体的子类,使用抽象类的匿名内部类
        return new Person(){

            @Override
            public void study() {
                System.out.println("good good Study,Day Day Up...");
            }
        };
    }
}

//定义一个子类
class Student extends  Person{

    @Override
    public void study() {
        System.out.println("good good Study,Day Day Up...");
    }
}

//测试类
public class Test1 {
    public static void main(String[] args) {
        //访问StudentDemo类中的method方法
        StudentDemo sd = new StudentDemo() ;
        Person person = sd.method(); //匿名内部类的本质:继承了该抽象类的子类对象
        person.study();
    }
}
举例2:
方法的返回值:引用类型 :接口
interface  Love{
    void love() ;
}
class LoveDemo{
    public Love function(){

        //匿名内部类---接口的匿名内部类
     return   new Love(){

            @Override
            public void love() {
                System.out.println("love JavaEE");
            }
        } ;

        //方式2
       /* Love love = new LoveImpl() ;//子实现类定义了
        return  love ;*/
    }
}

class  LoveImpl implements  Love{

    @Override
    public void love() {
        System.out.println("love Java");
    }
}
//测试类
public class Test2 {
    public static void main(String[] args) {
            LoveDemo ld = new LoveDemo() ;
        Love love = ld.function();
        love.love();
    }
}

二、API学习:object类

  1. 引入:
    后面学习 Java中核心类以及核心接口
    查看jdk提供API
    (Application Programming Interface) :应用程序接口文档
以后使用第三方技术--->学会看懂,并且应用文档
百度ai
定图定位
外卖配送
音乐app
..
..
直播平台(直播流文档)

现阶段:只需要去学习JDK的api
进入文档---->搜索"Object"

看这个类中
三个成员
字段 (成员变量)
构造方法(有几种方式能够创建对象)
方法(成员方法):有哪些功能(重点使用)
2. java.lang.Object类:
Object 是类层次结构的根类。
每个类都使用 Object 作为超类(父类),所有对象(包括数组)都实现这个类的方法。

  1. 常用功能:

           public final Class getClass(){} :
                   获取某个类或者接口的字节码文件对象  : class 包名.类名
    
           public int hashCode() :获取某个对象的哈希码值
                       ( 可以看成类似于 "地址值的东西")
    
           public String toString():表示一个对象的 "文本表现形式"
           public boolean equals(Object obj):使用某个对象与此对象进行比较!
    
          protected Object clone() throws CloneNotSupportedException  :克隆
    	子类(派生类)
    	
    	面试题:
       	获取字节码文件对象有几种方式? 三种
           	1)Object类的getClass()方法
    
举例1public class Student {  //父类就是Object类

    public Student(){
        super() ;
    }
}

public class ObjectDemo {
    public static void main(String[] args) {

        //  public final Class getClass(){} 获取正在运行的当前类的字节码文件对象
        /*
        *   getClass的源码:
        * public final native Class<?> getClass();   本地方法(native):非Java语言实现
        * */


        //创建一个学生类
        Student s = new Student() ;
        Class c1 =  s.getClass() ; //获取当前学生了类的字节码文件对象
        System.out.println(c1); //class com.qf.object_01.Student

        Student s2  = new Student() ;
        Class c2 = s2.getClass();
        System.out.println(c2);//class com.qf.object_01.Student
        System.out.println(c1==c2);   //c1和c2:都是正在运行的Java类对象(包名.Student.class---> 两个都是一样)
        System.out.println(s==s2);//两个对象进行比较:两个对象 == 比较是地址值

        System.out.println("---------------------------");

        //后期讲反射----->Class类中存在一个功能:
        //public String getName():获取以字符串形式表示的正在运行的java实体名称(类,接口...数组)
        String sName1 = c1.getName();
        String sName2 = c2.getName();
        System.out.println(sName1); //com.qf.object_01.Student
        System.out.println(sName2);//com.qf.object_01.Student


        System.out.println("---------------------------------");
        // public int hashCode() :获取某个对象的哈希码值 (了解)
        //由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数(一般情况下)
        // ( 可以看成类似于 "地址值的东西")
        //哈希码值:底层由内部地址值 进行计算的!
        int i1 = s.hashCode();
        int i2 = s2.hashCode();

        /*
        *    public native int hashCode();非Java语言实现
        * */
        System.out.println(i1);
        System.out.println(i2);
    }
}
举例2public class Person  extends  Object{

    String name ;//姓名
    int age ;//年龄
    public Person(){}
    public Person(String name,int age){
        this.name = name ;
        this.age = age ;
    }
    
    //重写Object类的toString
   /* public String toString(){
        return  "name:"+name+",age:"+age;
    }*/

   //快捷键:alt+ins--->toString():自动生成

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class ObjectDemo {
    public static void main(String[] args) {

        //   public String toString():表示一个对象的 "文本表现形式"
        //这个结果应该是易于读懂的信息表达式(建议所有子类都重写此方法。 )

        //创建一个人类:
        Person p = new Person("高圆圆",41) ;
        System.out.println(p);//com.qf.object_02.Person@1540e19d
        //如果直接输出对象名称 ,本质执行就是Object类的toString()
        System.out.println(p.toString());//com.qf.object_02.Person@1540e19d
        /*
        Object的toString源码
            public String toString() {
                    return getClass().getName() + "@" + Integer.toHexString(hashCode());
            }
        *
        * */
        System.out.println("---------------------------");
        Class pClass = p.getClass() ;
        String pClassName = pClass.getName();
        System.out.println(pClassName);//com.qf.object_02.Person
        //public static String toHexString(int i):int类型的对应Integer类型:

        System.out.println(pClassName+"@"+Integer.toHexString(p.hashCode()));
        System.out.println("---------------------------");

        Person p2 = new Person("文章",35) ;
        System.out.println(p2);
    }
}
举例3public class Student {
    String name ;
    int age ;

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    /**
     * alt+ins---生成hashCode()和equals()
     *
     */
    @Override
    public int hashCode() {  //比较是两个对象的成员的哈希码值是否相同
            //姓名不为空,算出来"姓名"的hashCode()
        int result = name != null ? name.hashCode() : 0; //this.name
        result = 31 * result + age; //31 *38806936 + 30
        return result;          //获取结果
    }

    /**
     *
     * @param o
     * @return
     */
    @Override
    public boolean equals(Object o) {  //s2          --->Object o =    new Student() ; //向上转型
        if (this == o) return true;//s1== s2
        if (o == null || getClass() != o.getClass()) return false; //this.getClass() != s2.getClass()

        Student student = (Student) o; //向下转型

        if (age != student.age) return false; //this.age 跟s2.age进行比较:
        return name != null ? name.equals(student.name) : student.name == null;
                            //姓名不为空:而姓名:String类型
                            //String:底层已经重写了Object的equals方法():默认字符串内容是否相同!
    }

   /* public static void main(String[] args) {

        System.out.println("高圆圆".hashCode());//38806936
    }
*/
}

Object类的public boolean equals(Object obj)方法
  使用其他对象和此对象进行比较
 
 
  ==:连接是两个基本数据类型,比较的是数据值是否相同
  如果连接的是两个引用数据类型,比较的是地址值是否相同
 
 
  equals方法:
       Object类的equals方法默认比较的两个对象的地址值是否相同,
 
      如果比较的内容相同,建议子类重写Object的equals方法
      注意:
       当此方法被重写时,通常有必要重写 hashCode 方法
 
 
       建议:所有的子类重写equals方法()同时重写hashCode()方法,比较的时候就比较的是两个对象的内容是否相同
               "内容",对象的成员信息是否一致!,如果一致就是true
 
public class ObjectDemo {
    public static void main(String[] args) {

        Student s1  = new Student("高圆圆",30) ;
        System.out.println(s1);
        Student s2 =  new Student("高圆圆",30) ;
        System.out.println(s1==s2) ;//false

        System.out.println("------------------------------");
        //public boolean equals(Object obj)
        System.out.println(s1.equals(s2));
        /*
        * Object类的equals源码:
        *  public boolean equals(Object obj) {
                    return (this == obj); //比较的是地址值
         }
        * */
        System.out.println("---------------------------------");

        //比较的一种写法:
        //String str3 = new String("hello") ;
        String str1 = "hello" ;
//        String str2 = "hello" ;
        String str2 = new String("hello") ;
        System.out.println(str1.equals(str2)) ; //true String类 底层重写了equals方法:比较是字符串内容是否相同!
    /*
    *
    * String类的equals方法的源码
    * class String{
    *  private final char value[]; //成员变量
    *
    * public boolean equals(Object anObject) {              //向上转型:Object anObject = new String() ;
        if (this == anObject) { //str1  == str2
            return true;
        }
        if (anObject instanceof String) {   //instanceOf: 判断前面对象数据类型是否为后面类型
            String anotherString = (String)anObject;  //向下转型
            int n = value.length;   //  int n = value.length ; ----> str1的字符串对应的字符数组长度 :5
            if (n == anotherString.value.length) {  //n == str2.value.length  5
                char v1[] = value;              //v1 = str1 = {'h','e','l','l','o'} ;
                char v2[] = anotherString.value; // //v2 = str2 = {'h','e','l','l','o'} ;
                int i = 0;                          //统计变量
                while (n-- != 0) {                  // 5-- != 0
                    if (v1[i] != v2[i]) {            //if(v1[0]!=v2[0]){ --- 'h' != 'h'
                        return false;
                    }
                         i++;
                }
                return true;
            }
        }
        return false;
    }
    * */
    }
}
举例4public class Worker  implements  Cloneable{ //标记当前这个类的字段是被克隆的
   private  String name ;

   private int 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;
    }

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

    @Override
    public String toString() {
        return "Worker{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    //调用Object类的clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
        /*
        * protected native Object clone() throws CloneNotSupportedException; 本地方法 :非Java语言实现
        * */
    }
}

protected Object clone()
               throws CloneNotSupportedException:克隆:创建对象并返回此对象的"副本"!
 
               浅克隆!
 
Object 类的 clone 方法执行特定的复制操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。
注意,所有的数组都被视为实现接口 Cloneable*

public class ObjectDemo {
    public static void main(String[] args) throws CloneNotSupportedException { //throws:表示抛出:  抛出异常的可能性!

        //创建一个工人类对象
        Worker w = new Worker("文章",30) ;
        System.out.println(w.getName()+"---"+w.getAge());

        //没有使用克隆之前
        Worker w2 = w ;//将地址值赋值 给w2
        System.out.println(w2.getName()+"---"+w2.getAge());
        System.out.println("--------------------------------");

        //使用Object类的clone方法
        //protected Object clone()
        //赋值对象的字段(成员变量)
        Object obj = w.clone();//因为这个方法本身有一个抛出异常,所以调用者调用该方法必须处理!
        Worker w3 = (Worker) obj; //向下转型
        System.out.println(w3);
        System.out.println(w3.getName()+"----"+w3.getAge());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

igfff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值