Java学习笔记--面向对象高级(内部类)
1 内部类1.1 内部类使用环境1.2 练习a01innerclassdemo1.Carpackage com.itstudy.a01innerclassdemo1; public class Car { String brand; int carAge; String color; Engine engine; //内部类 class Engine { private String brand; private int engineAge; } }a01innerclassdemo1.Testpackage com.itstudy.a01innerclassdemo1; public class Test { public static void main(String[] args) { /* 需求写一个Javabean类描述汽车 属性汽车的品牌车龄颜色发动机的品牌使用年限 内部类的意义 内部类表示的事物是外部类的一部分 内部类单独存在没有任何意义 */ } }1.3 小结2 内部类的分类2.1 分类2.2 成员内部类2.2.1 成员内部类内容2.2.2 练习a01innerclassdemo2.Outerpackage com.itstudy.a01innerclassdemo2; public class Outer { private class Inner { static int a 10; } //对外提供内部类对象 public Inner getInstance() { return new Inner(); } }a01innerclassdemo2.Testpackage com.itstudy.a01innerclassdemo2; public class Test { public static void main(String[] args) { /* 编写成员内部类的注意点 1.成员内部类可以被一些修饰符所修饰比如 private默认protectedpublicstatic等 2.在成员内部类里面JDK16之前不能定义静态变量JDK 16开始才可以定义静态变量。 获取成员内部类对象的两种方式 方式一外部类编写方法对外提供内部类对象(使用private修饰内部类时使用) 方式二直接创建 格式外部类名.内部类名 对象名 外部类对象.内部类对象; 范例Outer.Inner oi new Outer().new Inner(); */ //创建对象的方式 //类名 对象名 new 类名(); //Student s new Student; //我要创建的是谁的对象 //内部类的对象 //获取成员内部类对象的两种方式 //方式一直接创建 // Outer.Inner oi new Outer().new Inner(); //因为name是一个成员变量想要调用只能通过对象去调用 // System.out.println(new Outer().name); //当成员内部类被private修饰时外部类无法直接创建成员内部类对象 //方式二外部类编写方法对外提供内部类对象 //写法一 Outer o new Outer(); Object inner o.getInstance(); System.out.println(inner); //写法二 System.out.println(o.getInstance()); } }2.2.3 练习--调用a01innerclassdemo3.Outerpackage com.itstudy.a01innerclassdemo3; public class Outer{ private int a 10; class Inner{ private int a 20; public void show(){ int a 30; //Outer.this 获取了外部类对象的地址值 System.out.println(Outer.this.a); System.out.println(this.a);//20 System.out.println(a);//30 } } }a01innerclassdemo3.Testpackage com.itstudy.a01innerclassdemo3; import java.util.Scanner; public class Test { public static void main(String[] args) { //创建内部类的对象并调用show方法 Outer.Inner oi new Outer().new Inner(); oi.show(); Scanner sc new Scanner(System.in); sc.next(); //jps 11084 Test } }内部类的内存图2.2.4 小结2.3 静态内部类2.3.1 静态内部类内容a01innerclassdemo4.Outerpackage com.itstudy.a01innerclassdemo4; public class Outer { int a 10; static int b 20; //静态内部类 static class Inner { public void show1(){ //静态方法调用非静态变量需要创建对象进行调用 /* Outer o new Outer(); System.out.println(o.a); System.out.println(b);*/ System.out.println(非静态的方法被调用了); } public static void show2(){ /* Outer o new Outer(); System.out.println(o.a); System.out.println(b);*/ System.out.println(静态的方法被调用了); } } }a01innerclassdemo4.Testpackage com.itstudy.a01innerclassdemo4; public class Test { public static void main(String[] args) { //静态内部类 // 注意事项: //1.静态内部类也是成员内部类中的一种 //2.静态内部类只能访问外部类中的静态变量和静态方法 // 如果想要访问非静态的需要创建对象。 //创建静态内部类对象的格式 // 外部类名.内部类名 对象名 new 外部类名.内部类名(); //调用静态方法的格式 // 外部类名.内部类名.方法名(); //创建静态内部类的对象 //只要是静态的东西都可以用类名.直接调用 Outer.Inner oi new Outer.Inner(); oi.show1(); //非静态方法调用 Outer.Inner.show2(); //静态方法调用 } }2.3.2 小结2.4 局部内部类2.4.1 局部内部类内容a01innerclassdemo5.Outerpackage com.itstudy.a01innerclassdemo5; public class Outer { int b20; public void show() { int a 10; //局部内部类 class Inner { String name; int age; public void method1() { System.out.println(a); System.out.println(b); System.out.println(局部内部类中的method1方法); } public static void method2() { System.out.println(局部内部类中的method2静态方法); } } //创建局部内部类的对象 Inner i new Inner(); System.out.println(i.name i.age); i.method1(); Inner.method2(); } }a01innerclassdemo5.Testpackage com.itstudy.a01innerclassdemo5; public class Test { public static void main(String[] args) { /* 局部内部类 1.将内部类定义在方法里面就叫做局部内部类类似于方法里面的局部变量。 2.外界是无法直接使用局部内部类需要在方法内部创建对象并使用。 3.该类可以直接访问外部类的成员也可以访问方法内的局部变量。 */ //调用show方法让代码执行 Outer o new Outer(); o.show(); } }2.4.2 小结2.5 匿名内部类重点2.5.1 匿名内部类内容a01innerclassdemo6.Swim(interface)package com.itstudy.a01innerclassdemo6; public interface Swim { public abstract void swim(); }a01innerclassdemo6.Student//利用匿名内部类这个java文件可以没有已经在内部定义 package com.itstudy.a01innerclassdemo6; public class Student implements Swim{ Override public void swim() { System.out.println(学生正在游泳); } }a01innerclassdemo6.Testpackage com.itstudy.a01innerclassdemo6; public class Test { public static void main(String[] args) { /* 要求在测试类中调用下面的goSwimming方法 传统方式调用goSwimming方法 1. 新建java文件在文件当中新建Student类(实现重写方法) 2. 创建学生的对象 Student s new Student(); 3. 调用方法 goSwimming(s); 问题 如果Student类我只用到一次那么这个java文件单独新建有点浪费 我是否可以不新建这个Java文件只要里面的代码呢 匿名内部类的作用少定义一个Java文件 匿名内部类的定义格式 new 类名/接口名(){ 重写类/接口里面的方法; } 匿名内部类的定义格式 没有名字的Java类 继承/实现 重写方法 创建对象 最终格式可以理解为是一个没有名字的Java类的对象 没有名字的Java类大括号 Swim就是这个没有名字的Java类实现了swim接口 重写方法我们要在大括号当中重写Swim所有的抽象方法 创建对象new关键字作用的是后面这个合格没有名字的Java类创建了他的对象 整体创建了一个Swim实现类的对象只不过这个类没有名字而已 */ // 写法一 goSwimming(new Swim() { Override public void swim() { System.out.println(学生正在游泳); } }); //写法二 //多态 Swim ss new Student(); //多态 Swim s new Swim() { Override public void swim() { System.out.println(学生正在游泳); } }; goSwimming(s); } // 调用这个方法的时候需要传递Swim这个接口的实现类对象 public static void goSwimming (Swim s){ s.swim(); } }2.5.2 小结