内部类概述
内部类的概述
内部类的具体表现
特点:
1编译后会生成字节码文件, 也就是里面的inner在文件管理的bin目录下会生成后缀名为class的文件
即我们创建了内部类后bin目录下,就会在目录下会生成Outer.class文件和Outer$Inner.class两个文件
2内部类可以直接访问外部类的用private的成员,而不会破坏封装属性
(就是像下面的这个内部类里的方法可以访问外部类的私有属性)
class Outer(){
private String name;
class Inner(){
public void show(){
system.out.println(name);
3.可为外部类提供必要的功能组件
(就是外部类可以提供一些东西供内部类使用)
成员内部类
概念:在类的内部定义,与实列方法,实列变量同级别
外部类的一个实列部分,创建内部类时,必须依赖外部类
public class Outer(){
private String name;
private
然后想要对内部类进行调用
我们都知道,想要调用类中的方法,就需要先创建一个类对象
ackage day01;
//外部类
public class Outer {
private String name;
private int age=20;
//内部类
class Inner{
//这里的内部类看可以用修饰符修饰,即可用public和private来修饰
private String address="北京";
private String photo="111";
//内部类里定义一个方法
public void show(){
//打印外部类属性
System.out.println(name);
System.out.println(age);
//打印内部类的属性
System.out.println(address);
System.out.println(photo);;
}
}
}
图1是进行对外部类创建对象方法的操作,最后的结果将会调用内部类的方法
下面图2是在新类中进行调用前面内部类的操作
package day01;
public class test {
public static void main(String[] args) {
//如果现在想调用内部类中的方法,那么就需要执行下面操作
//因为我们知道如果想要调用另外一个类中的方法,则需要创建对象来调用
//方法1,创建外部类对象
Outer outer=new Outer();
Outer.Inner inner =outer.new Inner();
//注意:就是这里的左边只能做成 外部类.内部类这种格式就相当于是内部类了
System.out.println("------------");*/
//方法2,调用内部类方法
Outer.Inner inner=new Outer().new Inner();
inner.show();
}
}
注意::创建内部类对象的时候,要先创建外部类对象,然后用外部类对象名+点+new+内部类名
也就是内部类对象=
外部类.内部类类名 内部类对象名=外部类对象名 .new 内部类类名
——————————————————
注意:这样两行代码比较麻烦,我们可以节省为一行代码
即: 外部类.内部类类名 内部类对象名=new 外部类类名.new 内部类类名()
(直接缩写成一句话,简单多了,可能逻辑上不如上面的两行代码,先new外部类对象,在new内部类对象这样直接省了关于构建外部类对象名的那一步了)
特点4,关于内部类的优先级访问,当外部类和内部类属性重名(也就是图中都定义相同的比如 private String name)的时候,会优先访问内部类属性
但是如果真的想要访问外部类的属性,不要内部类,那么可以用this关键字指向外部类
具体操作:
外部类.this.属性名
相反内部类就不用这样操作了,因为本类内部类的优先级就比外部类要高
注意:上面图中,如果在内部类和外部类中都定义同一个成员属性 String name 字段,但是值不同,这时候,我们如果调用方法中的name值,则只能调用内部类中的name;如果我们想要不调用内部类的而调用外部类中的name,那么就可以使用this关键字
用法(外部类.this.name)就可以不调用内部类中的李四,而调用外部类中的张三。
特点5,成员内部类中是不能定义静态成员的,也就是说内部类中如果这样定义式会报错的
特点6,成员内部类中可以定义静态常量,就是内部类中可以用final来修饰字段,但是如果把final删了,那么就会报错
静态内部类(static)
概念:不依赖外部类对象,可直接
内部类添加static静态关键字修饰,那么内部类的级别就等同于外部类了
也就是外部类怎么操作,静态内部类也享受同样的待遇
那么既然级别都相同了那为什么还要定义个静态内部类呢?
(答:是因为静态内部类中需要定义些功能来供外部类使用)
//外部类
public class Outer {
private String name;
private int age=20;
//静态内部类
//注意:此时Inner的等级和Outer是相同的
static class Inner{
private String address="北京";
private String photo="111";
//注意:现在是静态内部类了,那么就可以添加静态成员
private static int num=10;
//1,下面是在内部类中创建一个show方法,然后通过show方法来访问外部类属性
public void show()
//因为内部类和外部类都已经处于同级的了,所以访问的话,直接是通过创建个对象,然后通过对象来访问
Outer outer=new Outer();
system.out.println(outer.name);
system.out println(outer.age);
//2.下面是访问静态内部类中的private属性
//可以直接通过调用属性来访问
system.out.println(address);
system.out.println(photo);
//3.下面是访问静态内部类中的静态属性
//因为我们在前面就学习到了,访问静态属性,直接是(类名.属性)调用
system.out println(Inner.num);
}
}
然后我们通过新建一个测试类来测试一下方法的结果
package day01;
public class test {
public static void main(String[] args) {
//注意下面的语句,创建对象是 类名()
//然后下面的Outer.Inner()是包含关系,实际表示的是Inner类的创建对象
Outer.Inner inner=new Outer.Inner();
//调用方法
inner.show();
}
}
局部内部类
概念:定义在外部类的方法当中,作用范围和创建对象范围仅仅局限在当前方法
public class Outer(){
private String name="刘德华";
private int age=60;
public void show(){
//在外部类的方法中,是可以直接访问定义的私有属性的,列如下面
private address="深圳";//这是局部属性,因为addresss只有在show这个方法中才能使用
//开始定义一个局部类,也就是在类中的方法中在定义一个新类,简称局部类,如下面的
class Inner(){
private phone="123544658";
private sex="男";
//然后在局部内中添加一个方法
public void show2(){
//访问外部类属性
system.out.println(Outer.this.name);
system.out.println(Outer.this.age);
//访问局部类属性
system.out.println(phone);
system.out.println(sex);
}
}
}
}
然后重新定义个test类来进行测设
package day01;
public class test {
public static void main(String[] args) {
//因为这里定义的是局部类,所以我们要进行调用测试的话
//需要先创建外部类对象,因为局部类在外部类中,所以先创建外部类对象
Outer outer=new Outer();
outer.show();
}
}
注意如果按照上面图片的测试类中的方式来进行调用,会出现错误,因为上面的调用,是创建外部类对象,然后调用show方法的时候,它定义了一个局部变量,然会下面定义了个类,但是这个类却并未使用,也就是并未参与关于的show方法的运算,则最后输出的效果就是啥都没有
所以我们想要使用局部类的东西,就要创建局部类对象,然后局部类调用方法
public class Outer(){
private String name="刘德华";
private int age=60;
public void show(){
//在外部类的方法中,是可以直接访问定义的私有属性的,列如下面
private address="深圳";//这是局部属性,因为addresss只有在show这个方法中才能使用
//开始定义一个局部内部类,也就是在类中的方法中在定义一个新类,简称局部内部类,如下面的
class Inner(){
private phone="123544658";
private sex="男";
//然后在局部内中添加一个方法
public void show2(){
//访问外部类属性
system.out.println(Outer.this.name);
system.out.println(Outer.this.age);
//访问内部类属性
system.out.println(phone);
system.out.println(sex);
//访问局部变量
system.out.println(address);
//值得注意的就是,在java的jdk版本1.8之后
//如果要访问局部变量,那么就相当于默认添加了个final修饰符
//意思就是我们不能在对访问的局部变量进行修改初始值
//在局部内部类不调用局部变量下 就是普通的变量 可以修改初始值
}
}
//即在这里创建局部类的对象,并调用方法
Inner inner=new Inner();
inner.show2();
}
}
最后,测试的结果就是会输出局部类里面的东西
注意:为什么我们只需要创建一个局部类的对象,然后局部类的对象只是调用show2方法,看起来Outer外部类和那个外部类中的方法,点参与感没有
是因为局部类的规则,局部类是定义在外部类的里面的子类 (类似于儿子的儿子的形状的东西)
匿名内部类
概念:和局部内部类相同,不过没有类名
常见用处:继承父类和实现接口
一个接口/类的方法的某个实现方式在程序中只会执行一次,但为了使用它,我们需要创建它的实现类/子类去实现/重写。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余。
下面详细说明一下
假设当前有一个接口,接口中只有一个方法
public interface Interface01 {
void show();
}
为了使用该接口的show方法,我们需要去创建一个实现类,同时书写show方法的具体实现方式
public class Interface01Impl implements Interface01{
@Override
public void show() {
System.out.println("I'm a impl class...");
}
}
如果实现类Interface01Impl全程只使用一次,那么为了这一次的使用去创建一个类,未免太过麻烦。我们需要一个方式来帮助我们摆脱这个困境。匿名内部类则可以很好的解决这个问题。
public static void main(String[] args) {
Interface01 interface01 = new Interface01() {
@Override
public void show() {
System.out.println("这里使用了匿名内部类");
}
};
//调用接口方法
interface01.show();
}
最后控制台结果显示,这里使用了匿名内部类