内部类
一、内部类概念
如果一个类的内部包含了另外一个类,则内部的那个类就称为内部类。
例如:身体和心脏的关系,汽车和发动机的关系。
分类:
- 成员内部类
- 局部内部类(包含匿名内部类)
二、成员内部类及其使用
(一)定义
定义格式:修饰符 class 类名称{
修饰符 class 类名称{
}
}
注意:内用外,可以随意访问,权限不受影响;外用内,一定需要借助内部类对象。
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(){}
public void SetName(String name){}
}
编译完成之后
Body.class
Body&Heart.class
(二)使用
1.间接使用:通过外部类的方法调用
public class Demo{
public static void main(String [] args){
Body body = new Body();
body.methodBody();
}
}
2.直接使用 :外部类名称.内部类名称 对象名 = new 外部类名称.new 内部类名称();
public class Demo1{
public static void main(String [] args){
Body.Heart heart = new Body().new Heart();
heart.beat();
}
}
(三)内部类同名变量访问
public class Outer{
int num =10;
public class Inner{
int num =20;
public void metnodInner(){
int num=30;
System.out.println(num);//局部变量就近原则
System.out.println(this.num);//内部类的成员变量
System.out.println(Outer.this.num);//外部类的成员变量
}
}
}
三、局部内部类
(一)定义和使用
- 如果一个类是定义在一个方法内部的,那么这就是一个局部内部类
- 局部:只有当前方法才能使用它,出了这个方法则不能使用
定义格式:
public class Outer{
public void methodOuter(){
class Inner{
int num = 10;
public void methodInner(){
System.out.println(num);
}
}
Inner inner= new Inner();
inner.methodInner();
}
}
class Demo{
putlic static void main(String [] args){
Outer obj = new Outer();
obj.methodOuter();
}
}
定义一个类的时候:权限修饰符如下
- 外部类:public default
- 成员内部类:public protected default private
- 局部内部类:什么都不写(不是default)
(二)局部内部类的final
- 局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是 有效final的
- java 8 开始,只要局部变量事实不变,那么final关键字可以省略。原因:new 出来的对象在堆内存中;局部变量是跟着方法走的,在栈当中;方法运行结束后,立刻出栈,局部变量就会立刻消失;new出来的对象在堆中当中持续存在,直到垃圾回收消失。所以复制一份保留常量。【生命周期的不一致导致需要常量。】
public class Outer{
public void methodOuter(){
class Inner{
//java 8 开始,只要局部变量事实不变,那么final关键字可以省略。
final int num = 10;
public void methodInner(){
System.out.println(num);
}
}
Inner inner= new Inner();
inner.methodInner();
}
}
四、匿名内部类
如果接口的实现类(或者是父类的子类)只需要使用唯一一次,这种情况下就可以省略掉该类的定义,而改为使用匿名内部类
public interface MyInterface{
void method();
}
public class MyInterfaceImpl{
public void method(){
System.out.println("接口实现方法");
}
}
public class Demo{
public static void main(String []args){
MyInterface obj= new MyInterfaceImpl();
obj.method();//-->接口实现方法
}
}
(一)格式
//0-1
MyInterface obj= new MyInterface(){
public void method(){
System.out.println("匿名内部类实现方法");
}
};
obj.method();//-->匿名内部类实现方法
(二)注意事项
- 匿名内部类在创建对象的时候,只能使用唯一一次。如果想通过匿名内部类创建多个对象,可以通过。但是通过实现类更加合适。
- 匿名对象只能调用一次方法,见程序0-2.想重复使用就要给对象命名,见程序0-1
//0-2
new MyInterface(){
public void method(){
System.out.println("匿名内部类实现方法");
}
}.method();
//-->匿名内部类实现方法
五、类、接口作为成员变量
public class hero{
private String name;
private int age;
private Weaon weapon;
private Skill skill;
//省略get set 构造
}
public class Weaon{
String code;
//省略get set 构造
}
public interface Skill{
void useKill();
}
public class Demo{
public static void main(String args[]){
Hero hero=new Hero();
hero.setName("艾希");
hero.setSkill(new SkillImpl);
SKill skill=new Sill(){
public void use(){}
};
}
}
六、接口做为方法的参数
public class Demo{
public static void main(String args[]){
List<String> = new ArrayList<>();//ArrayList 是list的实现类
}
public static List<String> addNames(List<String> list){
list.add("1");
list.add("2");
list.add("3");
list.add("4");
}
}
七、发红包案例
场景:红包发出之后所有人都有红包,最后一个红包给群主。
策略:普通红包,平均,余额放到最后一个红包中;手气红包,随机,最少1分钱,最多不超过平均数2倍。应该越发越少。
public class Bootstrap{
public static void main(String args[]){
MyRed red=new MyRed("标题");//图形界面
red.setOvnerName("设置群主名称");
red.setOpenWay(normal);//实现OpenWay接口
}
}




3678

被折叠的 条评论
为什么被折叠?



