内部类
如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类.
例如:身体和心脏的关系.又如:汽车和发动机的关系.
分类:
成员内部类
局部内部类(包含匿名内部类)
成员内部类
1 2 3 4 5 6 7
| 修饰符 class 类名称{ 修饰符 class 内部类名称{ } }
|
注意:内用外,随意访问;外用内,需要内部类对象.
如何使用成员内部类?有两种方式:
- 间接方式:在外部类的方法当中,使用内部类:然后main只是调用外部类的方法
- 直接方式:
1 2
| 类名称 对象名 = new 类名称(); [外部类名称.内部内名称 对象名 = new 外部类名称().new 内部类名称();]
|
Body类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.tipdm.Demo05;
public class Body {
public class Heart{ public void beat(){ System.out.println("心脏跳动:砰砰砰!"); System.out.println("我是:" + name); } }
private String name;
public Body() { }
public Body(String name) { this.name = name; }
public void methodBody(){ System.out.println("外部类的方法"); new Heart().beat(); }
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
|
demo1类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.tipdm.Demo05;
public class demo1 { public static void main(String[] args) { Body body = new Body("赵丽颖"); body.methodBody(); System.out.println("========================"); Body.Heart heart = new Body("冯绍峰").new Heart(); heart.beat(); } }
|
1 2 3 4 5 6 7 8
| 外部类的方法 心脏跳动:砰砰砰! 我是:赵丽颖 ======================== 心脏跳动:砰砰砰! 我是:冯绍峰
进程已结束,退出代码0
|
如果成员变量出现重复,那么如何从内部类获取外部类的成员变量呢?
Outer类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.tipdm.Demo05;
public class Outer { int num = 10;
public class Inner{ int num = 20; public void methodInner(){ int num = 30; System.out.println(num); System.out.println(this.num); System.out.println(Outer.this.num); } } }
|
demo2类:
1 2 3 4 5 6 7 8 9
| package com.tipdm.Demo05;
public class demo2 { public static void main(String[] args) { Outer.Inner inner = new Outer().new Inner(); inner.methodInner(); } }
|
局部内部类
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。
定义格式:
1 2 3 4 5 6 7
| 修饰符 class 外部类名称{ 修饰符 返回值类型 外部类方法名称(参数列表){ class 局部内部类名称{ } } }
|
Outer类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.tipdm.Demo06;
public class Outer { public void methodOuter(){ class Inner { int num = 10; public void methodInner(){ System.out.println(num); } } Inner inner1 = new Inner(); inner1.methodInner(); } }
|
在外部无法调用,局部内部类。
demo1类:
1 2 3 4 5 6 7 8
| package com.tipdm.Demo06;
public class demo1 { public static void main(String[] args) { Outer outer = new Outer(); outer.methodOuter(); } }
|
局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是[有效final的]。
备注:
- 从Java 8 开始,只要局部变量事实不变,那么final关键字可以省略.
原因:
new出来的对象在堆内存当中.
局部变量是跟着方法走的,在栈内存当中.
方法运行结束之后,立刻出栈,局部变量就会立刻消失.
但是new出来的对象会在堆当中持续存在,直到垃圾回收消失.
MyOuter类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.tipdm.Demo06;
public class MyOuter { public void methodOuter(){ final int num = 10; class MyInner{ public void methodInner(){ System.out.println(num); } } } }
|
匿名内部类
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。
匿名内部类的定义格式:
1 2 3
| 接口名称 对象名 = new 接口名称(){ }
|
对格式进行解析”new 接口名称(){ … }” 进行解析:
new代表创建对象的动作
接口名称就是匿名内部类需要实现哪个接口
{ … }这才是匿名内部类的内容.
另外还需要注意几点问题:
匿名内部类,在创建对象的时候,只能使用唯一一次.
第二次想要重复使用,必须重复创建.或者单独定义接口实现类.
匿名对象,在调用方法的时候,只能调用一次
如果希望同一个对象,调用多次方法,那么必须给对象起个名字
匿名内部类是省略了[实现类/子类名称].但是匿名对象是省略了[对象名称]
强调:匿名内部类和匿名对象不是一回事!!!
MyInterface接口:
1 2 3 4 5 6 7
| package com.tipdm.Demo07;
public interface MyInterface { void method();
void method2(); }
|
MyInterfaceImpl接口实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package com.tipdm.Demo07;
public class MyInterfaceImpl implements MyInterface{
@Override public void method() { System.out.println("覆盖重写了方法!11111111111"); }
@Override public void method2() { System.out.println("覆盖重写了方法!2222222222"); } }
|
DmoMain类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| package com.tipdm.Demo07;
public class DmoMain { public static void main(String[] args) { MyInterface obj = new MyInterfaceImpl(); obj.method();
MyInterface objA = new MyInterface() { @Override public void method() { System.out.println("匿名内部类实现了方法!111111111111AAAAAAAAAAA"); }
@Override public void method2() { System.out.println("匿名内部类实现了方法!22222222222AAAAAAAAAAAAAA"); } }; objA.method(); objA.method2();
System.out.println("======================"); new MyInterface() { @Override public void method() { System.out.println("又实现了匿名内部方法11111111bbbbbbbbbbb"); }
@Override public void method2() { System.out.println("匿名内部类实现了方法!22222222222BBBBBBBBBBBB"); } }.method(); new MyInterface() { @Override public void method() { System.out.println("又实现了匿名内部方法11111111bbbbbbbbbbb"); }
@Override public void method2() { System.out.println("匿名内部类实现了方法!22222222222BBBBBBBBBBBB"); } }.method2(); } }
|
1 2 3 4 5 6 7 8
| 覆盖重写了方法!11111111111 匿名内部类实现了方法!111111111111AAAAAAAAAAA 匿名内部类实现了方法!22222222222AAAAAAAAAAAAAA ====================== 又实现了匿名内部方法11111111bbbbbbbbbbb 匿名内部类实现了方法!22222222222BBBBBBBBBBBB
进程已结束,退出代码
|
类作为成员变量类型
Weapon武器类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.tipdm.Demo08;
public class Weapon { private String code;
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
public Weapon(String code) { this.code = code; }
public Weapon() { } }
|
Hero英雄类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.tipdm.Demo08;
public class Hero { private String name; private int age; private Weapon weapon;
public Hero() { }
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; }
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() + "攻击敌方!"); } }
|
demo类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.tipdm.Demo08;
public class demo { public static void main(String[] args) { Hero hero = new Hero(); hero.setName("盖伦"); hero.setAge(20);
Weapon weapon = new Weapon("多兰剑"); hero.setWeapon(weapon);
hero.attack(); } }
|
1 2 3
| 年龄为20的盖伦用多兰剑攻击敌方!
进程已结束,退出代码0
|
接口作为成员变量类型
Skill接口:
1 2 3 4 5
| package com.tipdm.Demo09;
public interface Skill { void use(); }
|
SkillImpl实现类:
1 2 3 4 5 6 7 8 9
| package com.tipdm.Demo09;
public class SkillImpl implements Skill{
@Override public void use() { System.out.println("Biubiubiu~~~~"); } }
|
Hero类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.tipdm.Demo09;
public class Hero { private String name; private Skill skill;
public void attack(){ System.out.println("我叫" + name + "开始释放极能!"); skill.use(); System.out.println("释放极能结束"); } public String getName() { return name; }
public Skill getSkill() { return skill; }
public void setSkill(Skill skill) { this.skill = skill; }
public void setName(String name) { this.name = name; }
public Hero(String name, Skill skill) { this.name = name; this.skill = skill; }
public Hero() { } }
|
DemoGame类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.tipdm.Demo09;
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("piapiapia!!!!!"); } }; hero.setSkill(skill);
hero.setSkill(new Skill() { @Override public void use() { System.out.println("xuxuxuxu~~~"); } }); hero.attack(); } }
|
1 2 3 4 5
| 我叫艾希开始释放极能! xuxuxuxu~~~ 释放极能结束
进程已结束,退出代码0
|
接口作为方法的参数和返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.tipdm.Demo10;
import java.util.ArrayList; import java.util.List;
public class demo { public static void main(String[] args) { List<String> list = new ArrayList<>();
List<String> result = addNames(list); for (int i = 0; i < result.size(); i++) { System.out.println(result.get(i)); } }
public static List<String> addNames(List<String> list){ list.add("迪丽热巴"); list.add("古力娜扎"); list.add("马尔扎哈"); list.add("沙场娜拉"); return list; } }
|
1 2 3 4 5 6
| 迪丽热巴 古力娜扎 马尔扎哈 沙场娜拉
进程已结束,退出代码0
|