Java基础补习---Day 12

一、内部类

(一)概述

        1、概述:定义在类的内部的类,和方法、变量等,均作为类的成员
        2、根据定义位置的不同,分为:
     (1)成员内部类
     (2)局部内部类
        3、成员内部类:
     (1)普通成员内部类
     (2)私有成员内部类
     (3)静态成员内部类
        4、根据表示方式的不同:
     (1)有名字的内部类
     (2)匿名内部类

(二)普通成员内部类

        1、定义在类成员位置的类,就是成员内部类
        2、格式:
class 外部类类名 {
    外部类成员;
    class 内部类类名 {
        内部类成员;
    }
}
public class Demo01_InnerClass {
    public static void main(String[] args) {
        //Heart01 h = new Heart01();
        //间接访问 创建外部类对象,外部类对象调用外部类方法,外部类方法访问内部类
        Body01 b = new Body01();
        b.test();
        //直接访问
        Body01.Heart01 hb = new Body01().new Heart01();
        System.out.println(hb.name);
    }
}
/**
* 外部类
* 1、内部类访问外部类
* 2、外部类访问内部类
* 3、外部类以外访问内部类
*/
class Body01 {
    String name = "外部类成员变量";
    public void test() {
        System.out.println("外部类的方法执行了");
        Heart01 h = new Heart01();
        //外部类可以访问内部类成员变量
        System.out.println(h.name);
        //外部类可以访问内部类成员方法
        h.show();
    }
    //内部类
    class Heart01 {
        String name = "内部类成员变量";
        public void show() {
            //内部类可以访问外部类成员变量
            System.out.println(name);
            //内部类可以访问外部类成员方法
            //test();
            System.out.println("nei部类的方法执行了");
        }
    }
}

(三)私有成员内部类

        1、在普通成员内部类的声明上加上 private 关键字
        2、格式:
class 外部类类名 {
    外部类成员;
    private class 内部类类名 {
        内部类成员;
    }
}
public class Demo01_InnerClass {
    public static void main(String[] args) {
        //Heart01 h = new Heart01();
        //间接访问 创建外部类对象,外部类对象调用外部类方法,外部类方法访问内部类
        Body01 b = new Body01();
        b.test();
        //私有内部类不能直接访问
        /*Body01.Heart01 hb = new Body01().new Heart01();
        System.out.println(hb.name);*/
    }
}
/**
* 外部类
* 1、内部类访问外部类
* 2、外部类访问内部类
* 3、外部类以外访问内部类
*/
class Body01 {
    String name = "外部类成员变量";
    public void test() {
        System.out.println("外部类的方法执行了");
        Heart01 h = new Heart01();
        //外部类可以访问内部类成员变量
        System.out.println(h.name);
        //外部类可以访问内部类成员方法
        h.show();
    }
    //内部类
    private class Heart01 {
        String name = "内部类成员变量";
        public void show() {
            //内部类可以访问外部类成员变量
            System.out.println(name);
            //内部类可以访问外部类成员方法
            //test();
            System.out.println("nei部类的方法执行了");
        }
    }
}

(四)静态成员内部类

        1、格式
class 外部类类名 {
    外部类成员;
    static class 内部类类名 {
        内部类成员;
    }
}
public class Demo02_Static {
    public static void main(String[] args) {
        Body02 b = new Body02();
        b.test1();
        b.test2();
        //静态内部类可以直接访问
        Body02.Heart02 hb = new Body02.Heart02();
        System.out.println(hb.name);
        System.out.println(hb.str);
        hb.test01();
        hb.test02();
    }
}
/**
* 只要遵循:静态不能访问非静态,非静态可以访问静态,静态可以访问静态
*/
class Body02 {
    String name = "非静态成员变量";
    static String str = "静态成员变量";
    public void test1() {
        Heart02 h = new Heart02();
        System.out.println(h.name + h.str);
        h.test01();
        h.test02();
        System.out.println("非静态成员方法执行了");
    }
    public static void test2() {
        Heart02 h = new Heart02();
        System.out.println(h.name + h.str);
        h.test01();
        h.test02();
        System.out.println("静态成员方法执行了");
    }
    //内部类
    static class Heart02 {
        String name = "neiBuLei非静态成员变量";
        static String str = "neiBuLei静态成员变量";
        public void test01() {
            //System.out.println(name);
            System.out.println(str);
            //test1();
            test2();
            System.out.println("neiBuLei非静态成员方法执行了");
        }
        public static void test02() {
            //System.out.println(name);
            System.out.println(str);
            //test1();
            test2();
            System.out.println("neiBuLei静态成员方法执行了");
        }
    }
}

(五)局部内部类

        1、概述:定义在方法中的类
        2、访问说明
     (1)方法中的局部变量在方法外不能被访问,局部内部类与局部变量同作为方法的成员,在方法之外不能访问,所以局部内部类在方法以外没有任何访问方式,并且必须先定义后调用;类似局部变量的先赋值后调用
     (2)解决方式:只能执行局部内部类所在的方法,在方法中创建局部内部类的对象,对调用其中的内容进行执行
public class Demo03_InnerMethod {
    public static void main(String[] args) {
        new Body03().show();
    }
}
class Body03 {
    String name = "外部类成员变量";
    public void test() {
        // 外部类不能直接访问局部内部类内容
        // Heart03 h = new Heart03();
        System.out.println("外部类成员方法");
    }
    public void show() {
        String name = "方法中的局部变量";
        //局部内部类
        class Heart03 {
            String name = "juBu局部内部类成员变量";
            public void demo() {
                //局部内部类可以访问自己的成员变量、局部内部类所在方法的局部变量,外部类的成员变量
                System.out.println(name);
                //局部内部类可以访问局部内部类所在的方法,外部类的成员方法
                //show();
                test();
                System.out.println("juBu局部内部类成员方法");
            }
        }
        //局部内部类只能在局部内部类所在的方法中进行访问,并且必须在局部内部类定义之后进行访问
        Heart03 h = new Heart03();
        System.out.println(h.name);
        h.demo();
    }
}

(六)匿名内部类

        1、概述:没有名字的内部类
        2、使用场景
     (1)实现抽象类
     (2)实现接口
        3、格式
new 抽象类类名或者接口名() {
    要实现的抽象方法;
};
        4、本质:
    (1)匿名内部类本质上是一个实现类对象
    (2)编译之后也会生成一个 .class 文件
public class Demo04_NoNameClassAndInter {
    public static void main(String[] args) {
        //第一种写法
        //父类引用指向子类对象:多态成员方法访问编译看左边,运行看后边
        //MyClass mc = new MyClass() {@Override public void test() {
            System.out.println("test方法执行了"); }};
            MyClass mc = new MyClass() {
            @Override
            public void test() {
            System.out.println("test方法执行了");
            }
        };
        mc.test();
        //接口的声明引用指向子实现类对象
        MyInter mi = new MyInter() {
            @Override
            public void show() {
                System.out.println("show方法执行了");
            }
        };
        mi.show();
        //第二种写法
        new MyClass() {
            @Override
            public void test() {
                System.out.println("test000方法执行了");
            }
        }.test();
        new MyInter() {
            @Override
            public void show() {
                System.out.println("show0000方法执行了");
            }
        }.show();
    }
}
abstract class MyClass {
    public abstract void test();
}
interface MyInter {
    public abstract void show();
}

二、Object

(一)概述

        1、 Object 是所有类层次结构的根类,是所有类的直接或者间接父类
        2、随意定义一个类型,不显示继承哪个类,就默认继承 Object

(二)常用方法

        1、 getClass () :获取当前对象所属的类型
        2、 hashCode () :根据对象的情况,计算对象的哈希码值
        3、 toString () :重写后:返回对象的字符串表示形式
        4、 finalize () :当垃圾回收器确定后面该对象不再被使用的时候,就有该对象的垃圾回收器调用此方法,清理空间(对象)
public class Demo05_Methods {
    public static void main(String[] args) {
        Person p1 = new Person("张三", 23);
        //class com.hqyj.demos.Person:获取当前对象所属类型
        System.out.println(p1.getClass());
        //460141958:根据对象的情况,计算对象的哈希码值
        System.out.println(p1.hashCode());
        //重写前:com.hqyj.demos.Person@1b6d3586
        //重写后:Person{name='张三', age=23}
        System.out.println(p1.toString());
    }
}
class Person {
    String name;
    int age;
    //alt + insert + toString()
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

(三)equals方法

        1、用于比较两个对象是否相等,这两个对象为调用者对象和参数对象
        2、在 Object 类型中,比较的是两个对象的地址值是否相等
        3、在所属类型中重写 equals 方法之后,比较的是地址值
import java.util.Objects;
public class Demo06_Equals {
    public static void main(String[] args) {
        Student stu1 = new Student("张三", 23);
        Student stu2 = new Student("张三", 23);
        System.out.println(stu1.equals(stu2));
    }
}
class Student {
    private String name;
    private int age;
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
        Objects.equals(name, student.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                }';
    }
    public Student() {
    }
    public Student(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;
    }
}

 

(四)==equals的区别

        1、共同点:都是用于比较数据是否相等的方式
        2、不同点:
     (1)==:是一个运算符; equals :是一个方法
     (2) == :可以比较基本数据类型,也可以比较引用数据类型; equals :只能比较引用数据类型
     (3) == :比较基本数据类型比较属性值,比较引用数据类型比较地址值; equals :重写前比较地址值,重写后比较属性值

三、StringBuilder

(一)概述

        1、 StringBuilder 是一个可变字符序列,因为在类中提供了对应修改的方法
        2、 StringBuilder 底层是数组,封装了对底层操作的方法

(二)构造方法

        1、 StringBuilder () :创建一个字符串生成器,初始容量为 16
        2、 StringBuilder (int capacity) :创建一个字符串生成器,初始容量为参数指定
        3、 StringBuilder (String str) :创建一个字符串生成器,初始容量为 16+str 的长度
        4、 capacity () :返回字符串生成器的容量
        5、 length () :返回字符串缓冲区中字符的个数
public class Demo07_StringBuilder {
    public static void main(String[] args) {
        //初始容量为16
        StringBuilder sb = new StringBuilder();
        System.out.println(sb.capacity());
        System.out.println(sb.length());
        StringBuilder sb1 = new StringBuilder(10);
        System.out.println(sb1.capacity());
        System.out.println(sb1.length());
        StringBuilder sb2 = new StringBuilder("abc");
        System.out.println(sb2.capacity());
        System.out.println(sb2.length());
    }
}

(三)添加功能

        1、 append (int i) :将任意类型的参数追加到当前课表字符序列之后
        2、底层操作:当字符串个数和当前数组容积进行比较,如果溢出,就做数组的拷贝,将原有数组的内容添加到新的数组中,其中,新数组的容积为【原来容积<< 1 + 2
        3、 insert (int offset, int i) :任意数据类型插入到指定位置
public class Demo08_Append {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        System.out.println(sb.capacity());
        for (int i = 1; i <= 71; i++) {
            //sb.append("1");
            sb.insert(0, "1");
        }
        //16 34 70 142 286 [<< 1 + 2]
        System.out.println(sb.capacity());
    }
}

(四)比较+拼接和Stringbuilder

public class Demo09_Question {
    public static void main(String[] args) {
        //+拼接 StringBuilder StringBuffer
        //testString();
        testStringBuilder();
        testStringBuffer();
    }
    public static void testStringBuffer() {
        StringBuffer sb = new StringBuffer("");
        long start = System.currentTimeMillis();
        for (long i = 0; i < 70000000; i++) {
            sb.append(i);
        }
        long end = System.currentTimeMillis();
        System.out.println("StringBuffer:" + (end - start));
    }
    private static void testStringBuilder() {
        StringBuilder sb = new StringBuilder("");
        long start = System.currentTimeMillis();
        for (long i = 0; i < 70000000; i++) {
            sb.append(i);
        }
        long end = System.currentTimeMillis();
        System.out.println("StringBuilder:" + (end - start));
    }
    private static void testString() {
        String str = "";
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            str += i;
        }
        long end = System.currentTimeMillis();
        System.out.println("String:" + (end - start));
    }
}

(五)StringBuilderStringBuffer

        1、共同点:都是可变字符序列,都是字符串生成器,都是字符串缓冲区
        2、不同点:
     (1)线程安全性不同
        StringBuilder:安全性低
        StringBuffer:安全性高
     (2)效率不同:
        StringBuilder:效率高
        StringBuffer:效率低
     (3)版本
        StringBuilder: JDK1.5
        StringBuffer: JDK1.0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值