内部类—相关操作
-
成员内部类
-
Body类
package cn.xiaoge.day11.demo03; public class Body { // 外部内 public class Heart { // 成员内部类 // 内部类的方法 public void beat() { System.out.println("心脏跳动: 蹦蹦蹦! "); System.out.println("我叫: " + name); // 正确写法! } } // 外部类的成员变量 private String name; // 外部类的方法 public void methodBody() { System.out.println("外部类的方法"); new Heart().beat(); } public String getName() { return name; } public void setName(String name) { this.name = name; } } -
执行路口
package cn.xiaoge.day11.demo03; /* 如果一个事物的内部包含另一个事物, 那么这就是一个类内部包含另一个类. 例如: 身体和心脏的关系. 又如: 汽车和发动机的关系. 分类: 1. 成员分类 2. 局部内部类(包含匿名内部类) 成员内部类的定义格式: 修饰符 class 外部类名称{ 修饰符 class 内部类名称{ // ... } // ... } 注意: 内用外, 随意访问; 外用内, 需要内部类对象. =============================== 如何使用成员内部类?有两种方式: 1. 间接方式: 在外部类的方法当中, 使用内部类: 然后main只是调用外部类的方法. 2. 直接方式: 公式: 类名称 对象名 = new 类名称(); [外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();] */ public class Demo01InnerClass { public static void main(String[] args) { Body body = new Body(); // 外部类对象 // 通过外部类的对象, 调用外部类的方法, 里面间接在使用内部类Heart body.methodBody(); System.out.println("======================"); // 按照公式写 Body.Heart heart = new Body().new Heart(); heart.beat(); } } // 运行结果 外部类的方法 心脏跳动: 蹦蹦蹦! 我叫: null ====================== 心脏跳动: 蹦蹦蹦! 我叫: null
-
-
内部类访问外部类的成员变量
-
Outer类
package cn.xiaoge.day11.demo03; // 如果出现个了重名现象, 那么格式是: 外部类名称.this.外部类成员变量名 public class Outer { int num = 10; // 外部类的成员变量 public class Inner { int num = 20; // 内部类的成员变量 public void methodInner() { int num = 30; // 内部类方法的局部变量 System.out.println(num); // 30 局部变量, 就近原则 System.out.println(this.num); // 20 内部类的成员变量 System.out.println(Outer.this.num); // 10 外部类的成员变量 } } } -
执行路口
package cn.xiaoge.day11.demo03; public class Demo02InnerClass { public static void main(String[] args) { // 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称(); Outer.Inner inner = new Outer().new Inner(); inner.methodInner(); } } // 运行结果 30 20 10
-
-
局部内部类
-
Outer类
package cn.xiaoge.day11.demo04; /* 如果一个类是定义在一个方法内部的, 那么这就是一个局部内部类. "局部": 只有当前所属的方法才能使用它, 除了这个方法外面就不能使用了. 定义格式: 修饰符 class 外部类名称 { 修饰符 返回值类型 外部类方法名称(参数列表) { class 局部内部类名称 { // ... } } } 小节一个类的权限修饰符: public > protected > (default) > private 定义一个类的时候, 权限修饰符规则: 1. 外部类: public / (default) 2. 成员内部类: public / protected / (default) / private 3. 局部内部类: 什么都不能写 */ public class Outer { public void methodOuter() { class Inner { // 局部内部类 int num = 10; public void methodInner() { System.out.println(num); // 10 } } Inner inner = new Inner(); inner.methodInner(); } } -
执行路口
package cn.xiaoge.day11.demo04; public class DemoMain { public static void main(String[] args) { Outer obj = new Outer(); obj.methodOuter(); } } // 运行结果 10
-
-
局部内部类访问方法的局部变量
-
必须是有效的final成员变量
package cn.xiaoge.day11.demo04; /* 局部内部类, 如果希望访问所在方法的局部变量, 那么这个局部变量必须是[有效final的]. 备注: 从Java 8+开始, 只要局部变量数值不变, 那么final关键字可以省略. 原因: 1. new出来的对象在堆内存当中. 2. 局部变量是跟着方法走的, 在栈内存当中. 3. 方法运行结束之后, 立刻出栈, 局部变量就会立刻消失. 4. 但是new出来的对象会在堆当中持续存在, 直到垃圾回收消失. */ public class MyOuter { public void methodOuter() { // num变量只能赋值一次, 再次赋值时 下面的局部内部类引用的num就会报错 int num = 10; class MyInner { public void methodInner() { System.out.println(num); } } } }
-
-
匿名内部类
-
MyInterface接口
package cn.xiaoge.day11.demo05; public interface MyInterface { public abstract void method1(); // 抽象方法 public abstract void method2(); // 抽象方法 } -
MyInterfacImpl实现类
package cn.xiaoge.day11.demo05; public class MyInterfacImpl implements MyInterface { // @Override // public void method() { // System.out.println("实现类覆盖重写了方法! "); // } @Override public void method1() { System.out.println("111111111111111"); } @Override public void method2() { System.out.println("222222222222222"); } } -
执行路口
package cn.xiaoge.day11.demo05; /* 如果接口的实现类 (或者是父类的子类) 只需要使用唯一的一次. 那么这种情况下就可以省略掉该类的定义, 而改为使用[匿名内部类]. 匿名内部类的定义格式: 接口名称 对象名 = new 接口名称() { // 覆盖重写所有抽象方法 } 对格式"new 接口名称() {...}"进行解析: 1. new代表创建对象的动作 2. 接口名称就是匿名内部类需要实现那个接口 3. {...}这才是匿名内部类的内容 另外还要注意几点问题: 1. 匿名内部类, 在[创建对象]的时候, 只能使用唯一一次. 如果希望多次创建对象, 而且类的内容一样的话, 那么就必须单独定义实现类了. 2. 匿名对象, 在[调用方法]的时候, 只能调用唯一一次. 如果希望同一对象, 调用多次方法, 那么必须给对象起个名字. 3. 匿名内部类是省略了[实现类/子类名称], 但是匿名对象是省略了[对象名称] 强调: 匿名内部类和匿名对象不是一回事!!! */ public class DemoMain { public static void main(String[] args) { // MyInterface obj = new MyInterfacImpl(); // obj.method(); // MyInterface some = new MyInterface(); // 错误写法 // 使用匿名内部类, 但不是匿名对象, 对象名称就叫objA MyInterface objA = new MyInterface() { @Override public void method1() { System.out.println("匿名内部类实现了方法! 111-A"); } @Override public void method2() { System.out.println("匿名内部类实现了方法! 222-A"); } }; objA.method1(); objA.method2(); System.out.println("================================="); // 使用匿名内部类, 而且省略了对象名称, 也是匿名对象. new MyInterface() { @Override public void method1() { System.out.println("匿名内部类实现了方法! 111-B"); } @Override public void method2() { System.out.println("匿名内部类实现了方法! 222-B"); } }.method1(); // 因为匿名对象无法调用第二次方法, 所以需要在创建一个匿名内部类的匿名对象. new MyInterface() { @Override public void method1() { System.out.println("匿名内部类实现了方法! 111-B"); } @Override public void method2() { System.out.println("匿名内部类实现了方法! 222-B"); } }.method2(); } } // 运行结果 匿名内部类实现了方法! 111-A 匿名内部类实现了方法! 222-A ================================= 匿名内部类实现了方法! 111-B 匿名内部类实现了方法! 222-B
-
-
类作为成员变量类型
-
Hero类
package cn.xiaoge.day11.demo06; // 游戏当中的英雄角色类 public class Hero { private String name; // 英雄的名字 private int age; // 年龄 private Weapon weapon; // 武器 public Hero() { } public Hero(String name, int age, Weapon weapon) { this.name = name; this.age = age; this.weapon = weapon; } public void attack() { System.out.println("年龄为" + age + "的" + name + "正在用" + weapon.getCode() + "攻击敌方."); } 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; } public Weapon getWeapon() { return weapon; } public void setWeapon(Weapon weapon) { this.weapon = weapon; } } -
Weapon类
package cn.xiaoge.day11.demo06; public class Weapon { private String code; // 武器的代号 public Weapon() { } public Weapon(String code) { this.code = code; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } } -
执行路口
package cn.xiaoge.day11.demo06; public class DemoMain { public static void main(String[] args) { // 创建一个英雄角色 Hero hero = new Hero(); // 为英雄起一个名字, 并且设置年龄 hero.setName("盖伦"); hero.setAge(20); // 创建一个武器对象 Weapon weapon = new Weapon("霜之哀伤"); // 为英雄配备武器 hero.setWeapon(weapon); // 年龄为20的盖伦正在用霜之哀伤攻击敌方. hero.attack(); } } // 运行结果 年龄为20的盖伦正在用霜之哀伤攻击敌方.
-
-
接口作为成员变量类
-
Skill接口
package cn.xiaoge.day11.demo07; public interface Skill { public abstract void use(); // 释放技能的抽象方法 } -
Hero类
package cn.xiaoge.day11.demo07; public class Hero { private String name; // 英雄的名称 private Skill skill; // 英雄的技能 public Hero() { } public Hero(String name, Skill skill) { this.name = name; this.skill = skill; } public void attack() { System.out.println("我叫" + name +", 开始施放技能: "); skill.use(); // 调用接口中的抽象方法 System.out.println("施放技能完成! "); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Skill getSkill() { return skill; } public void setSkill(Skill skill) { this.skill = skill; } } -
执行路口
package cn.xiaoge.day11.demo07; public class DemoGame { public static void main(String[] args) { Hero hero = new Hero(); hero.setName("李白"); // 设置英雄的名称 // 使用匿名内部类 // Skill skill = new Skill() { // @Override // public void use() { // System.out.println("凤凰飞天! "); // } // }; // 设置英雄的技能 // hero.setSkill(skill); hero.setSkill(new Skill() { @Override public void use() { System.out.println("凤凰起飞! "); } }); hero.attack(); } } // 运行结果 我叫李白, 开始施放技能: 凤凰起飞! 施放技能完成!
-
-
接口作为方法的参数或返回值
-
DemoInterface类
package cn.xiaoge.day11.demo07; import java.util.ArrayList; import java.util.List; public class DemoInterface { public static void main(String[] args) { List<String> list = new ArrayList(); List<String> result = addName(list); for (int i = 0; i < result.size(); i++) { System.out.println(result.get(i)); } } public static List<String> addName(List<String> list) { list.add("古力娜扎"); list.add("杨幂"); list.add("高圆圆"); list.add("金泫雅"); return list; } } // 运行结果 古力娜扎 杨幂 高圆圆 金泫雅
-
浙公网安备 33010602011771号