匿名内部类,Object类的基础知识

2 篇文章 0 订阅
1 篇文章 0 订阅

局部内部类

  1. 概念:一个类的方法体中定义一个类,这个类就是局部内部类。
  2. 特点:
    • 可以直接访问外部类的成员(包括私有成员)。
    • 不能直接被外界访问,需要外界创建外部类的对象,外部类对象调方法,在方法中创建内部类的对象,再使用局部内部类的对象访问其成员。
  3. 局部内部类访问局部变量,这个局部变量默认加(1.8之后)final修饰,因为局部变量随着方法调用完毕而消失,而局部对象并没有立刻消失,还要使用局部变量,所以局部变量加上final变成常量,延长生命周期。

示例:

public class Test4 {
    public static void main(String[] args) {
//        局部内部类不能在测试类中创建对象直接访问
//        需要创建外部类对象,通过外部类对象调用方法
//        在方法中创建内部类的对象,然后内部类对象访问成员
        Animal animal = new Animal();
        animal.getName();
    }
}

class Animal {
    public void getName() {
//        局部变量默认有final修饰
        final int b=20;
        class Demo {
            int a=10;
            public void show() {
                System.out.println(b);
                System.out.println(a);
                System.out.println("局部内部类");
            }
        }
//        创建局部内部类的对象
        Demo demo = new Demo();
        demo.show();
    }
}

匿名内部类

  1. 它是局部内部类的简化写法

  2. 前提:要有一个类(可以是抽象类或者非抽象类)或者接口

  3. 格式:new 类名/接口名(){

    ​ 重写方法 ; }

  4. 它本质上是一个对象,是继承该抽象类或接口的子类对象。(所以常常使用此特性快速的创建抽象类或者接口的子类对象)

示例:
public class Test1 {
    public static void main(String[] args) {
    // 匿名内部类创建抽象类的对象使用。
        Student s = new Student() {

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

            @Override
            public void show2() {
                System.out.println("show222222");

            }
        };
        s.show();
        new Student() {

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

            @Override
            public void show2() {
                System.out.println("show222222");
            }
        }.show2();
    }
}
abstract class Student {
    public abstract void show();

    public abstract void show2();
}
  1. 可以给匿名内部类起名,使用类名调方法。这样就可以使用同一个对象。

  2. 匿名内部类作为参数或者返回值使用。(如果形参是一个抽象类类型或者接口类型,应该传递该类的字对象,可以使用匿名内部类是对象这个特点。)

    示例:
    public class Test7 {
        public static void main(String[] args) {
            new Food() {
                
                @Override
                public Food test(Food food) {
                    System.out.println("=======");
                    return food;
                }
            }.test(
    //                形参是Food类型的,所以应该传入一个该类的子对象,不用
    //                创建继承关系的子类,直接使用匿名内部类创建子类传递。
                    new Food() {
                        @Override
                        public Food test(Food food) {
                            System.out.println("666666");
                            return food;
                        }
                    }
    //                由于test方法被重写,返回值是一个Food类型的对象,
    //                所以可以直接再调方法
            ).test(
                    new Food() {
                        @Override
                        public Food test(Food food) {
                            return food;
                        }
                    }
            );
        }
    }
    
    abstract class Food {
        public abstract Food test(Food food);
    }
    
    
    示例2
     interface Inter {
    		public static final int a = 23 ;
    	}
    	
    	public class Test {
    
    		public static void main(String[] args) {
    			new Inter() {
    				public void show() {
    					//this 代表匿名内部类 或者说接口的子类对象。(代表调取该方法的对象,匿名内部类【Inter的子类对象】调了该方法)。this代表子类对象,子类对象又继承了父类,所以this.a=23
    					System.out.println(this.a);//23
    		
    				}
    			}.show();
    		}
    	}
    

常用API的使用

  1. API:就是应用程序接口(Application programming Interface)
  2. java API:就是Java提供给我们使用的类,这些类底层实现被隐藏,我们不需要知道具体底层怎么实现,但是要会使用。

Object

  1. Object 是类层次的根类(是所有子类的顶层父类)。

  2. 所有类都直接或者间接继承该类。

  3. 常见对象

    • hashcode()方法:
      • 返回一个对象的哈希码值。不同对象的哈希码值一般不同,但是同一个对象的哈希码值相同。哈希码值不是对象的地址值,可以理解为逻辑值。
    • get Class()方法:
      • 返回此 Object 的运行时类(就是获取该类字节码文件的对象)
      • 一个类的字节码文件对象只有一个。
    • toString()方法:
      • 我们在输出一个对象时,会输出该对象的地址值。默认该对象会调取toString方法。
      • 此方法功能是输出该对象的字符串表现形式。
      • 如果觉得此方法无实际意义时,可以重写此方法。
    • equals()方法:
      • 引用数据类型:比较两个引用的地址值是否相同。
      • 不满意此功能可以改写,例如:字符串类型的调用此方法就会对比字符串类容是否相同。
    equals方法重写示例:
    public class Test3 {
        public static void main(String[] args) {
            Teacher teacher = new Teacher("小王", 24);
            Teacher teacher1 = new Teacher("小王", 24);
            System.out.println(teacher.equals(teacher1));
            System.out.println("=========");
            System.out.println(teacher.equals(teacher));
            System.out.println("========");
            Teacher teacher2 = new Teacher("李老师", 31);
            Teacher teacher3 = new Teacher("高老师", 31);
            System.out.println(teacher2.equals(teacher3));
        }
    }
    
    class Teacher {
        private String name;
        private int age;
    
        public Teacher(String name, int age) {
            this.name = name;
            this.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;
        }
    
        @Override
        public boolean equals(Object obj) {
    //        重写逻辑功能要求,考虑要周到,逻辑功能要健全,执行效率要高。
    
           /*
           这个判断输入的两个对象地址是否相同,相同就是同一个对象,那么内容肯定相同,
            不用再做下列判断,直接给出结果就行。
            */
            if (this == obj) {
                return true;
            }
    //        传进来的对象用多态的形式传进来的,object是所有类的父类,obj就可以接受任何类的对象。
    //        如果传入的不是Teacher类的对象,那么没有判断,就会执行报错,给用户造成困扰,应该给出提示。
    //        此处判断传进来的对象(obj)是不是该类(Teacher)的对象
            if (obj instanceof Teacher) {
                Teacher th = (Teacher) obj;
                boolean b = this.name.equals(th.name) && this.age == th.age;
                return b;
            } else {
                return false;
            }
        }
    }
    
    • equals和==的区别:

      • equals只能比较引用数据类型,
      • ==:可以比较基本数据类型,会比较两个值是否相同。引用数据类型,会比较两个引用的地址值是否相同。
    • clone()方法:

      • 开辟一个新空间,复制一个对象进去。
      • 调用克隆方法要注意下列几点
        • 因为clone方法的权限修饰符是protected,在测试类中不能被访问,所以在调用clone方法的对象的类中要重写此方法,只修改方法的权限修饰符。
        • 调用clone方法的对象的类要实现Cloneable这个接口。
        • 克隆的对象类型时Object 。
        • 调用clone属于浅克隆:只是克隆了对象本身,没有把对象内部的引用克隆。
    public class Test8 {
        public static void main(String[] args) throws CloneNotSupportedException {
            Basketball basketball = new Basketball(30);
            basketball.piayBasketball();
            System.out.println("===========");
            Object obj = basketball.clone();
            Basketball ba=(Basketball)obj;
            System.out.println(ba.price);
            ba.piayBasketball();
        }
    }
    
    //一个对象要被克隆,应该继承标记接口Cloneable
    class Basketball  implements Cloneable{
        public Basketball() {
        }
    
        public Basketball(int price) {
            this.price = price;
        }
    
        int price=10;
         void piayBasketball(){
            System.out.println("打球");
        }
    //clone 权限修饰符是protected,在测试类中不能被访问到,这里clone方法,就只是修改权限修饰符
    //    方法重写子类的权限修饰符权限大于等于父类,所以此处可以改为public。
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值