内部类:
-
概念:在一个类的内部再定义一个完整类的类。
-
特点:1、编译之后可生成独立的字节码文件。
2、内部类可以直接访问外部类的私有成员,而不破坏封装。
3、可以为外部提供封装的属性
class Outer{
private String name;
class Header{
public void show(){
System.out.println(name);
}
}
}
成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类。
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象。 //必须创建外部的类,才能再创建内部的类
public class Outer{
private String name="张三";
private int age = 20;
class Inner{
private String address="北京";
private String phone="110";
public void show(){
//打印外部类的属性
System.out.println(name);
System.out.println(age);
//打印内部类中的属性
System.out.println(address);
System.out.println(phone);
}
}
}
public class TestOuter{
public static void main(String[] agrs){
//1创建外部类对象
Outer outer=new Outer();
//2创建内部类对象
Inner inner = Outer.new Inner();
inner.show();
//可以合一步
inner inner=new Outer().new Inner();
inner.show();
}
}
-
当外部类、内部类存在重名属性时,会有限访问内部类属性。
//如果想访问外部的实例变量 Outer.this.name;
自编案例:
class Outer { private String name = "你好"; class Inner { int num = 10; public void show() { int num = 20; System.out.println(num);//输出20。注:定义了局部变量,则为局部变量值;如果没有定义,则等同于this.num;********这个务必搞清楚!!!!!容易出错,很多大佬都直接省略this调用实例变量 System.out.println(this.num);//输出10 System.out.println(Inner.this.num);//输出10 System.out.println(Outer.this.name);//输出你好 } } public static void main(String[] args) { new Outer().new inner().show(); } }
-
成员内部类,是无法定义静态变量的,但是可以定义静态常量
静态内部类
-
不依赖外部类对象,可以直接创建或通过类名访问,可声明静态成员。
package operator; public class Outer { private String name = "xxx"; private int age = 18; //静态内部类,其级别和外部类相同 static class Inner { private String address = "上海"; private String phone = "110"; //静态成员 private static int count=1000; public void show(){ //调用外部类的属性呢 //1先效用外部类对象 Outer outer=new Outer(); //2调用外部类对象的属性 System.out.println(outer.name); System.out.println(outer.age); //调用静态内部类的属性和方法 System.out.println(address); System.out.println(phone); //调用静态内部的静态属性 System.out.println(Inner.count); } } public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); inner.show(); } }
1、两个都是非静态的成员内部类,可以观察细节,直接new 内部的的class,它本质是先创建了外部的类的一个实例,再接着创建内部类的的实例,因此内部的类,可以直接调用外部类的所有的属性,包括不限于static 变量,变量,方法等。这种做法是,我认为是为了解决java单继承的这个缺点。这样子搞了之后,以后需要外部的方法,直接Outer.方法就行了。对应python中就相当于闭包这个知识点。
2、静态内部类,你调用内部的静态变量,你可以发现,是没有初始化外部的类,因此,外部的非静态变量,无法直接调用,只能调用static的方法,所以必须new创建里实例,才可以调用。
对比下非静态成员内部类的new方法。
//非静态内部类
inner inner=new Outer().new Inner();
//静态内部类
Outer.Inner inner = new Outer.Inner();
对比发现了吗?
非静态类new的是Outer带括号,而静态的不带括号。这就意味着非静态内部类new的时候,创建了Outer的的实例,而静态内部类没有创建。主要的区别是在这里。
附上另外一个案例:便一目了然
package operator;
public class TestOut {
int a = 1;
static int b = 2;
private int c = 3;
private static int d = 4;
//非静态内部类
class Inner1 {
int a =5;
void test() {
System.out.println(a); //外部类属性,得出5
System.out.println(TestOut.this.a);//得出1
System.out.println(b); //外部类静态属性,得出2
System.out.println(c); //外部私有类属性,得出3
System.out.println(d); //外部静态私有类属性,得出4
}
}
//静态内部类
static class Inner2 {
void test() {
TestOut testOut = new TestOut();
System.out.println(testOut.a); //创建外部的实例,即可调用;得出1
// System.out.println(a);//外部类属性 有错误
System.out.println(b); //外部类静态属性,得出2
// System.out.println(c); //外部私有类属性 有错误
System.out.println(d); //外部静态私有类属性,得出4
}
}
public static void main(String[] args) {
new TestOut().new Inner1().test();
System.out.println("---------------");
new TestOut.Inner2().test();
}
}
局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
- 局部内部类访问外部类当中方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。
package operator;
public class Outer {
private String name = "liudehua";
private int age = 35;
public void show() {
//定于局部变量
String address = "深圳";
//局部内部类:注意不能加任何访问修饰符
class Inner {
private String phone = "144";
private String email = "xxx@mai.com";
public void show2() {
//访问外部类的属性
System.out.println(Outer.this.name);
System.out.println(Outer.this.age);
//访问内部类的属性
System.out.println(this.phone);
System.out.println(this.email);
}
}
//创建局部内部类对象
Inner inner = new Inner();
inner.show2();
}
public static void main(String[] args) {
Outer outer = new Outer();
outer.show();
}
}
匿名内部类
- 没有类名的局部内部类(一切特征都与局部内部类相同)。
- 必须继承一个父类或者实现一个接口。
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
- 优点:减少代码量
- 缺点:可读性交叉
//Usb.java 接口
public interface Usb {
//服务
void service();
}
-------------------------------
//Mouse.java 实现接口
public class Mouse implements Usb{
@override
public void service{
System.out.println("连接电脑成功。鼠标开始工作");
}
}
-------------------------------
//TestUsb.java
public class TestUsb {
public static void main(String[] args){
//创建接口类型的变量
Usb usb=new Mouse();
usb.service();
}
class Fan implements Usb{
@Overide
public void service(){
System.out.println("连接电脑成功,风扇开始工作了。。")
}
}
//使用局部内部类创建对象
Usb usb=new Fan();
usb.service();
//使用匿名内部类来优化(相当于创建了一个局部内部类)
Usb usb=new Usb(){
@Override
public void service(){
System.out.println("连接电脑成功,风扇开始工作了");
}
};
Usb.service;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)