一个类的内部嵌套了另一个类,这个类叫内部类,是类的第五大成员(属性,方法,构造器,代码块,内部类)。
内部类最大的特点就是可以直接访问私有属性,它本质上还是一个类。
基本语法:
public class Localinner { //外部其他类public static void main(String[] args) {}
}
class Outer{ //外部类class Inner{ //内部类}
}
class Other{ //外部其他类
}
内部类可具体分为四种。
定义在外部类局部位置上(比如方法或者代码块内):
局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。
它有以下几个特点:
示例代码:
public class LocalInnerClass {public static void main(String[] args) {Outer02 outer02 = new Outer02();outer02.m1();}
}
class Outer02{ //外部类private int n1 = 100; //外部类私有属性private void m2(){ //外部类私有方法System.out.println("外部类私有方法");};public void m1(){ //外部类的m1()方法class Inner02{ //内部类(这个类不能添加访问修饰符,但是可以用final修饰(不想让同一个方法内的其他内部类继承))private int n1=200;public void f1(){System.out.println("外部类私有属性"+"n1="+Outer02.this.n1); //访问外部类属性 (哪个对象调用了m1()方法,Outer02.this指的就是哪个对象,比如在这里它指的就是Outer02这个对象本身)System.out.println("内部类私有属性"+"n1="+this.n1); //访问内部类属性m2(); //访问外部类方法}}class Inner03 extends Inner02{ //另一个内部类继承}Inner03 inner03 = new Inner03(); //外部类在方法中创建这个内部类inner03.f1();}
}
输出结果:
案例引入:
需求:想使用A接口,并创建对象
public class Test {public static void main(String[] args) {A outerClass = new Tiger();();}
}
interface A { //接口public void cry();
}
class Tiger implements A{@Overridepublic void cry() {System.out.println("老虎叫....");}
}
匿名内部类是定义在外部类的局部位置,比如方法中或者代码块中,并且没有类名,对象实例化出来后该内部类就消失了(但是对象还是可以反复使用)。
基本语法:
new类或接口(参数列表){
类或接口里的东西
};
基于接口的匿名内部类
示例代码如下。
public class AnonymousInnerClass { //外部其他类public static void main(String[] args) {OuterClass outerClass = new OuterClass();hod();}
}
class OuterClass{ //外部类private int n1=10;public void method(){//编译类型是A,运行类型就是这个匿名内部类A tiger = new A(){ //使用new接口(){}的方式创建匿名内部类@Overridepublic void cry() {System.out.println("老虎叫..叫..");}};System.out.println("tiger的运行类型="Class()); //获取tiger对象的运行类型();}
}
interface A { //接口public void cry();
}
接口是不能被直接new出来的,所以在jdk的底层实现实际上是经过了如下转换。(jdk底层在创建匿名内部类OuterClass$1,立即马上就创建了0uter04$1实例,并且把地址返回给tiger)
class XXXX implements A{ //这个xxxx就是这个匿名内部类的名字,但是是由系统自动去分配的(分配规则是-->外部类名$1 之后每个匿名内部类的编号都会以第一个外部类名为主自增)@Overridepublic void cry() {System.out.println("老虎叫..叫..");}
}
基于类的匿名内部类
和基于接口的方式相似,
示例代码如下。
public class AnonymousInnerClass {public static void main(String[] args) {OuterClass outerClass = new OuterClass();hod();}
}
class OuterClass{public void method(){//基于类的匿名内部类Father a = new Father("cjy"){ //注意这里是有带{ }的,所以是一个匿名内部类,而且这里的cjy会传给Father的构造器{System.out.println("这是一个匿名内部类");}};}
}
class Father {public Father(String name){}public void test(){}
}
实际上在jdk的底层实现实际上是经过了如下转换的。
class xxxxx2 extends Father {}
还有一点要注意的是如果是基于抽象类创建匿名内部类的话里面的抽象方法必须重写。
练习使用:
要求如下。
public class AnonymousInnerClassDemo2 {public static void main(String[] args) {CellPhone cellPhone = new CellPhone();//当做实参直接传递,简洁高效cellPhone.alarmclock(new Bell() {@Overridepublic void ring() {System.out.println("懒猪起床了");}});cellPhone.alarmclock(new Bell() {@Overridepublic void ring() {System.out.println("小伙伴上课了");}});}
}
interface Bell{void ring();
}
class CellPhone{public void alarmclock(Bell bell){bell.ring();}
}
运行结果:
总结:匿名内部类也可以理解为另一种局部内部类(特点和局部内部类相似)只不过是没有名字而且只能实例一次,也通常被用于临时需要重写一些类或接口的方法,简化开发(某些类只想用一次,使用匿名内部类会自己去实现接口或继承类,我们只需要重写方法)。
定义在外部类的成员位置上:
成员内部类是定义在外部类的成员位置(跟属性,方法,代码块,构造器同级),并且没有static修饰。
成员内部类有下面几个特点:
代码示例:
public class MemberInnerClass {public static void main(String[] args) {Outerclass outerClass = new Outerclass();outerClass.t1();//外部其他类拿到成员内部类对象的两种方式//第一种方式Outerclass.Innerclass innerclass1 = w Innerclass();//第二种方式Outerclass.Innerclass innerclass2 = outerClass.t2();}
}
class Outerclass{ //外部类private int n1 = 10;public String name = "张三";public void m1(){ //外部类的私有方法}class Innerclass{ //成员内部类private int n1 = 20;public void say(){System.out.println("n1 = "+ Outerclass.this.n1); //使用外部类私有属性System.out.println("n1 = "+ n1); //使用内部类私有属性m1(); //调用外部类私有方法}}public void t1(){///创建成员内部类的对象,然后使用相关的方法Innerclass innerclass = new Innerclass();innerclass.say();}//返回一个成员内部类对象public Innerclass t2(){///创建成员内部类的对象,然后使用相关的方法return new Innerclass();}
}
静态内部类是定义在外部类的成员位置,并且有static修饰。
成员静态内部类有下面几个特点。
示例代码:
public class StaticMemberInnerClass {public static void main(String[] args) {//创建外部类Outer outer = new Outer();outer.m1();//外部其他类访问静态内部类对象(两种方式)//第一种方式 (直接创建)Outer.Inner inner1 = new Outer.Inner(); //直接使用不需要new(前提是满足访问权限)inner1.say();//第二种方式 (通过方法的返回值获得对象)Outer.Inner inner2 = outer.m3();inner2.say();}
}
class Outer{ //外部类private int n1 = 10;private static String name = "张三";public static class Inner{ //静态成员内部类private static String name = "张四";public void say(){System.out.println(Outer.name); //只能访问静态属性(访问外部类属性)System.out.println(name); //只能访问静态属性(访问内部类属性)}}//成员方法创建内部类public void m1(){Inner inner = new Inner();inner.say();}//返回一个静态成员内部类对象public Inner m3(){return new Inner();}
}
我的学习地址
本文发布于:2024-01-29 17:12:43,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170651956516945.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |