常用类和内部类总结
目录内容
- 目录
- 什么是内部类
- 重点概念: 在一个类的内部再定义一个完整的类
- 重点:内部类的特点:
- 练习
- 内部类可直接访问外部类的私有成员 而不破坏封装
- 成员内部类
- 练习
- //如果内部类属性和外部类属性的名字相同时 //会优先调用内部类的属性 //但是如果想调用外部类的属性 //方法中使用该代码 // System.out.println(Outer.this.name);
- //下行代码为打印内部类属性和外部类属性名字相同时 //打印外部类的属性
- 静态内部类
- 重点 成员内部类对象创建的时候要依赖外部类对象 而静态内部类创建的时候不需要依赖外部类对象
- 练习
- //静态内部类(静态内部类就是在成员内部类前面加一个static) //而静态内部类相当于和外部类的意义相同
- //静态内部类调用外部类的属性和自己的属性 //1 先创建外部类对象的 Outer outer = new Outer(); //2 调用外部类对象的属性 System.out.println(outer.name); //调用静态内部类的属性和方法 //直接调用 System.out.println(address); System.out.println(phone); //调用静态内部类的静态属性 System.out.println(Inner.count);
- //直接创建内部类对象 Outer.Inner inner=new Outer.Inner(); //调用方法 inner.show();
- 匿名内部类
- 在继承一个父类或者实现一个接口的时候 匿名内部类用的比较多
- 练习
- //在main方法中写一个 //局部内部类(用局部内部类创建一个对象) class Fan implements USB{ @Override public void service() { System.out.println(" 局部内部类 连接电脑成功 风扇开始工作...."); } } //使用局部内部类创建对象 //接口去创建一个它的实现类对象 USB usb2=new Fan(); usb2.service();
- //由于使用局部内部类对象只用一次 //而局部内不类就不用了
- //所以使用匿名内部类优化 //接口不能实例化 //相当于创建了一个局部内部类(匿名内部类) //重点 这里是USB接口而不是Fan局部内部类 //所以这里写的是USB而不是Fan // 同样这里不止可以用接口创建匿名内部类 //也可以用父类创建匿名内部类...抽象类等等也可以创建 USB usb=new USB() { @Override public void service() { System.out.println(" 匿名内部类 连接电脑成功 开始工作..."); } }; usb.service();
- Object类
- API文档注解:Object类
- getClas()方法
- Object类中的第一个方法getClass()
- getClass()方法返回的是引用存储的实际对象类型 例如下图代码重点理解!!!
- hashCode()方法
- Object类中的第二个方法hashCode()方法
- 哈希值根据对象的地址或者字符串或数字使用hash算法计算出来的int类型的数值
- 一般情况下相同对象返回相同的哈希码 所以我们一般用哈希码来判断两个是不是同一个对象
- 练习
- toString()方法
- Object类中的第三个方法toString()方法
- 练习
- equals()方法
- Object类中的第四个方法equals()方法
- 当两个对象的属性相同时 可以发现进行比较 返回的值仍为false 重点 所以为了避免出现这种情况 可进行覆盖(重写)来 比较两个的对象的内容是否相同!!! 重点 步骤为:
- 练习
- 重点: 认真理解以下代码的意义!!!
- @Override public boolean equals(Object obj) { //步骤一 判断两个对象是否是同一个引用 if (this == obj){ return true; } //步骤二 obj是否为null if (obj==null){ return false; } //步骤三 判断是否为同一类型 //方法一 判断是否为同一类型 //if (this.getClass()==obj.getClass()){}
- //方法二 判断是否为同一类型 //instanceof 可以用来判断对象是否是某种类型 //也可以来判断两个类之间是否存在父子关系 if (obj instanceof Student){ //步骤四 强制类型转换 Student s=(Student) obj; //步骤五 比较属性 if (this.name.equals(s.getName())&&this.age==s.getAge()){ return true; } } //否则返回false return false; }
- finalize()方法
- Object类中的第五个方法finalize()方法
- finalize()方法是回收垃圾方法 由于JVM是自动调用回收垃圾机制 但是我们也可以手动来调用垃圾回收 所用我们要覆盖(重写)finalize()方法
- 练习
- //覆盖finalize()方法 @Override protected void finalize() throws Throwable { System.out.println(this.name+"对象被回收了"); }
- //在打印结果中可以看出 当创建出对象时 对象赋予属性 //对象不是垃圾 所以下面代码不是垃圾 Student s1 = new Student("aaa", 20); Student s2 = new Student("bbb", 20); Student s3 = new Student("ccc", 20); Student s4 = new Student("ddd", 20); Student s5 = new Student("eee", 20);
- //而没有创建出对象时 只给赋予属性这些属于垃圾 new Student("AAA", 20); new Student("BBB", 20); new Student("CCC", 20); new Student("DDD", 20); new Student("EEE", 20); System.gc(); System.out.println("回收垃圾");
- 什么是包装类
- 基本类型(八大基本类型)的数据都存在栈中 而且栈中存储的都是对象的地址 引用类型的数据都存在堆中 例如: 为了给基本类型提供更强大功能 所以给基本类型提供了包装类 等等...
- 类型转换和装箱 拆箱
- 理解什么是装箱和拆箱
- 练习一
- // 类型转换: 装箱 即基本类型(栈)转为引用类型(堆)的过程 // 类型转换: 拆箱 即引用类型(堆)转为基本类型(栈)的过程
- 练习二
- hex 十六进制 Binary 二进制 octal 八进制
- //练习 基本类型和字符串之间的转换 重点: //方法二拓展: 将基本类型转换为2进制 4进制 8进制 16进制的字符串类型
- //基本类型和字符串之间的转换 //1 基本类型转成字符串 int n1=255; //方法一: 使用加号加上"" String s1=n1+""; //方法二:使用Integer中的toString()方法 String s2 = Integer.toString(n1); //方法二拓展: 将基本类型转换为2进制 4进制 8进制 16进制的字符串类型 String s22=Integer.toString(n1,16); System.out.println(s1); System.out.println(s2); System.out.println(n1+"的16进制的字符串类型 "+s22);
- //2 字符串转成基本类型 //注意点:字符串类型的数字中不能掺杂其他字母或者符号 //否则会出现NumberFormatException异常 String str="150"; //使用 Integer.parseXXX()方法 int n2 = Integer.parseInt(str); System.out.println("----------字符串转成基本类型----------"); System.out.println(n2);
- 整数缓冲区
- 整数缓冲区的作用 在实际应用中 对已经创建的对象进行复用
- 改正 :应该为-127到128之间 下面的数据范围是错误的
- 练习
- 重点 整数缓冲区 当Integer的数据大于-127到小于128的时候 Integer数据就会在堆中的整数缓冲区中找到它原本就创建的这个数据来调用 但是如果不是这个范围的话 就会重新创建一个数据 所以两者的Boolean打印值是不同的
- String类
- 程序运行过程中有三个空间:栈 堆 方法区 栈里面存储基本类型数据 堆里面存储引用类型数据和对象 方法区中存储字符串池(注意Jdk版本有不同的变化)
- 当使用new 一个新的String的时候 会产生两个对象 堆和池中会各自储存一个
- //创建字符串的第一种方式 String name="hello";//"hello" 常量时储存在字符串池中的 name="zhangsan";//"zhangsan"赋值给name变量时,给字符串赋值时 //并没有修改数据 而是重新开辟一块空间
- 练习
- 对比上面图片一块学习
- 重点: Java代码中 等号==比较的是对象存储地址 而equals比较的是数据
- //创建字符串的第一种方式 String name="hello";//"hello" 常量时储存在字符串池中的 name="zhangsan";//"zhangsan"赋值给name变量时,给字符串赋值时 //并没有修改数据 而是重新开辟一块空间 String name2="zhangsan"; //当重新创建一个字符串时 而是先找字符串池中有没有这个变量 没有的话会重新 //开辟一块空间来创建这个命名变量
- //创建字符串的第二种方式 String str=new String("java"); String str2=new String("java"); System.out.println("java等号比较结果- --》"+(str == str2));//false // 原因:Java代码中 等号==比较的是对象存储地址 System.out.println("java中equals比较结果-- -》"+str.equals(str2));//true //原因 :而equals比较的是数据
- String常用方法
- 大总结
- 练习
- //字符串String常用方法的使用 //length();返回字符串的长度 //charAt(int index);返回某个位置的字符 //contains(String str);判断是否包含某个字符串
- //toCharArray();返回字符串对应的数组 //indexOf();返回字符串首次出现的位置 //lastIndexOf();返回字符串最后一次出现的位置
- //trim(); 去掉字符串前后的空格 //toUpperCase(); 将小写转为大写 //toLowerCase(); 将大写转为小写 //endWith(str); 判断是否以str结尾 //startWith(str); 判断是否以str开头
- // replace(char old, char new); //用新的字符或字符串替换旧的字符或字符串 // split(); 对字符串进行拆分
- //equalsIgnoreCase 忽略字母的大小写来进行比较字符串是否相等
- //compareTo 比较的是字符串 第一个字母的十进制数字进行比较 //只要两个字符串的前面个字符不相同那么就进行比较 直接相减 然后打印出来 //后面的字符无论写多少都不进行比较 只比较第一个 // 97-129=-23
- //如果两个的字符串 第一个字母相同 那么就进行比较第二个 跟上面方法相同
目录
什么是内部类
重点概念: 在一个类的内部再定义一个完整的类
重点:内部类的特点:
一 编译之后可生成独立的字节码文件
二 内部类可直接访问外部类的私有成员 而不破坏封装
三 可为外部类提供必要的内部功能组件
练习
内部类可直接访问外部类的私有成员 而不破坏封装
成员内部类
在类的内部定义 与实例变量 实例方法同级别的类
外部类的一个实力部分 创建内部类对象时 必须依赖外部类对象
练习
//如果内部类属性和外部类属性的名字相同时
//会优先调用内部类的属性
//但是如果想调用外部类的属性
//方法中使用该代码
// System.out.println(Outer.this.name);
//下行代码为打印内部类属性和外部类属性名字相同时
//打印外部类的属性
静态内部类
重点
成员内部类对象创建的时候要依赖外部类对象
而静态内部类创建的时候不需要依赖外部类对象
练习
//静态内部类(静态内部类就是在成员内部类前面加一个static)
//而静态内部类相当于和外部类的意义相同
//静态内部类调用外部类的属性和自己的属性
//1 先创建外部类对象的
Outer outer = new Outer();
//2 调用外部类对象的属性
System.out.println(outer.name);
//调用静态内部类的属性和方法
//直接调用
System.out.println(address);
System.out.println(phone);
//调用静态内部类的静态属性
System.out.println(Inner.count);
//直接创建内部类对象
Outer.Inner inner=new Outer.Inner();
//调用方法
inner.show();
匿名内部类
(没有名字的局部内部类 一切特征都与局部内部类相同)