什么是内部类
内部类的分类
内部类特点:
内部类语法:
class Outer { class Inner { // 也会生成class文件 } }
// 创建外部类对象 Outer outer = new Outer(); // 创建内部类对象 Outer.Inner inner = outer.new Inner();
package classes.demo01; //成员内部类 //外部类 public class Outer { //实例变量 private String name="小明"; private int age =18; private static int ages=20; public void show(){ System.out.println("外部类的方法"); } //内部类 class Inner{ private String name="李四"; private String email="188888888"; //成员内部类不能定义静态成员static,但可以包含静态常量 final private static final String country="中国"; public void innershow(){ System.out.println("内部类的方法"); //打印外部类的属性,属性和外部类的属性名字相同,需要使用 Outer.this 才能打印出小明 System.out.println(name);// 默认打印李四 System.out.println(Outer.this.name); System.out.println(Outer.this.age); System.out.println(Inner.country); //类名.属性 打印静态的属性 //打印内部类的属性 System.out.println(this.name); System.out.println(this.email); } } }
package classes.demo01; public class Test { public static void main(String[] args) { /* //1 创建外部类对象 Outer outer = new Outer(); //2 创建内部类对象 Outer.Inner inner = outer.new Inner(); inner.innershow(); */ //一步的写法 Outer.Inner inner = new Outer().new Inner(); inner.innershow(); } }
内部类的方法 李四 小明 18 中国 李四 188888888
不依赖外部类,可直接创建或通过类名访问,可声明静态成员
相当于一个外部类,级别和外部类相同外部类可以包含什么,这个内部类就可以包含什么
只能直接访问外部类的静态成员(实例成员需实例化外部类对象)
Outer.Inner inner = new Outer.Inner(); Outer.Inner.show();
可以在内部类前加 static 修饰,加了static修饰符之后,静态内部类级别与外部类相同。(只有内部类才可以static修饰,普通的类不可以)
package classes.demo02; //静态内部类 public class Outer { private String name="张三"; private int age=20; public void show(){ System.out.println("外部类的方法"); } //静态内部类:和外部类相同,一个级别 static class Inner{ private String address="北京"; private String phone="12345678"; //静态成员 private static int count=1000; public void innerShow(){ System.out.println("静态内部类的方法"); //调用静态内部类的属性 System.out.println(address); System.out.println(phone); //调用静态内部类的静态属性 System.out.println(Inner.count); //调用外部类的属性时 //1 先创建外部类对象 Outer outer = new Outer(); outer.show(); //2 调用外部类对象属性 System.out.println(outer.age); System.out.println(outer.name); } } }
package classes.demo02; public class Test { public static void main(String[] args) { //调用静态内部类方法 // 直接创建静态内部类对象 Outer.Inner inner = new Outer.Inner(); //调用方法 inner.innerShow(); } }
静态内部类的方法 北京 12345678 1000 外部类的方法 20 张三
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
局部内部类不能加任何访问修饰符;
局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final
限制类的使用范围。
package classes.demo03; //局部内部类 public class Outer { private String name="小子"; private int age=12; public void show(){ //定义局部变量 // jdk1.8及以后自动添加final final int phone=66; final String address="上海"; //局部内部类:注意不能加任何访问修饰符 class Inner{ //局部内部类的属性 private String email="1234556677"; private String phone = "123456"; public void innerShow(){ System.out.println("局部内部类方法"); //局部内部类的属性 System.out.println(email); System.out.println(phone); //访问外部类属性 System.out.println(name);//省略了outer.this System.out.println(Outer.this.name); System.out.println(Outer.this.age); //访问局部变量,jdk1.7要求,局部变量必须时常量, // jdk1.8及以后自动添加final System.out.println(address); System.out.println("上海"); } } //创建局部类对象 Inner inner = new Inner(); inner.innerShow(); } }
package classes.demo03; public class Test { public static void main(String[] args) { // 创建外部类对象调用 Outer outer = new Outer(); outer.show(); } }
局部内部类方法 1234556677 123456 小子 小子 12 上海 上海
没有类名的局部内部类(一切特征都与局部内部类相同)
必须继承一个父类或者实现一个接口
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象(以实现接口为例,先创建一个名为 Inter 的接口,内部方法为 method。通常创建一个局部内部类是有类名称的,而上述匿名内部类相当于创建了一个没有名字的局部内部类来实现了 Inter 接口,是一个语法合并的形式)
优点:减少代码量 缺点:可读性较差
package classes.demo04; //接口 public interface Usb { //服务方法 void service(); }
package classes.demo04; public class Mouse implements Usb { @Override public void service() { System.out.println("连接USB成功,鼠标开始工作"); } }
package classes.demo04; import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput; import org.w3c.dom.ls.LSOutput; public class Test { public static void main(String[] args) { class fan implements Usb{ @Override public void service() { System.out.println("连接USB成功,风扇开始工作"); } } //使用局部内部类创建对象 Usb usb1 = new fan(); usb1.service(); // 使用匿名内部类优化(相当于创建了一个局部内部类) Usb usb = new Usb(){//new 后面可以是接口也可以是抽象类或者父类 大括号里重写方法 @Override public void service() { System.out.println("连接风扇成功,开始工作了"); } }; // 注意后面的 ; usb.service(); } }
连接USB成功,风扇开始工作 连接风扇成功,开始工作了
超类、基类,所有类的直接或间接父类,位于继承树的最顶层
任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承
Object类中所定义的方法,是所有对象都具备的方法
Object类型可以存储任何对象
作为参数:可接受任何对象
作为返回值:可返回任何对象
public final Class<?> getClass() {}
public int hashCode (){}
public String toString(){}
public boolean equals(Object obj){}
可进行覆盖(重写),比较两个对象的内容是否相同
equals()方法覆盖步骤:
1.比较两个引用是否指向同一个对象
2.判断obj是否为null
3.判断两个引用指向的实际对象类型是否一致
4.强制类型转换
5.依次比较各个属性值是否相同
垃圾对象:没有有效引用指向此对象时,为垃圾对
垃圾回收:由gc销毁垃圾对象,释放数据存储空间
自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象
手动回收机制:使用System.gc();通知JVM执行垃圾回收
package classes.demo06; import java.util.Objects; public class Student { private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student() { } public Student(int age, String name) { this.age = age; this.name = name; } //快捷建:Alt+enter 选toString 方法 @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + '}'; } @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(age, name); } //打印finalize 会有提示重写 @Override protected void finalize() throws Throwable { System.out.println(this.name+"垃圾被清理了"); } }
package classes.demo06; public class TestStudent { public static void main(String[] args) { // 1. getClass()方法 : System.out.println("----------------1. getClass()-----------------"); Student student1 = new Student(20,"aaa"); Student student2 = new Student(20,"ccc"); //判断S1和S2是不是同一个类型 if (student1.getClass()==student1.getClass()){ System.out.println("是同一类型"); }else{ System.out.println("不是同一类型"); } //2.hashcode() 方法 System.out.println("----------------2.hashcode() -----------------"); Student student3 = new Student(); Student student4 = new Student(); System.out.println(student3.hashCode()); System.out.println(student4.hashCode()); Student student5=student3; System.out.println(student5.hashCode()); //3. toString 方法 System.out.println("----------------3. toString -----------------"); System.out.println(student1.toString()); System.out.println(student2.toString()); //4.equals() 方法 判断两个对象是否相等 System.out.println("----------------4. equals() -----------------"); Student student6 = new Student(17, "小子"); Student student7 = new Student(17, "小子"); System.out.println( student6.equals(student7)); } }
----------------1. getClass()----------------- 是同一类型 ----------------2.hashcode() ----------------- 961 961 961 ----------------3. toString ----------------- Student{age=20, name='aaa'} Student{age=20, name='ccc'} ----------------4. equals() ----------------- true
package classes.demo06; public class TestStudent2 { public static void main(String[] args) { //System.gc(); 垃圾回收 Student student1 = new Student(17,"aaaa"); Student student2 = new Student(17,"bbbb"); Student student3 = new Student(17,"cccc"); new Student(17,"ddddd"); new Student(17,"eeeee"); new Student(17,"fffff"); // 回收垃圾 使用System.gc();通知JVM执行垃圾回收 System.gc(); System.out.println("垃圾已经回收"); } }
垃圾已经回收 eeeee垃圾被清理了 fffff垃圾被清理了 ddddd垃圾被清理了
————————————————————————————————————————————————————————————————————————————
千峰教育-常用类