1.内部类概念
1.内部的完整结构又只为外部事物提供服务,那么这个内部完整结构最好使用内部类。
在java中可以将一个类在另一个或者一个方法内部,前者称为内部类后者称为外部类。
2.我现在有一个类,要描述一个对象,但是这个对象是由多个对象组成的,如火车,火车是由若干一样的车厢组成,我要想组成火车就需要多个车厢,而这个车厢就可以理解为内部类。
有点像组合
3.内部类分为
静态内部类
实例内部类
匿名内部类
局部内部类
2.内部类代码实现
1.新建一个包名字为demoinnerclass
2.定义一个类是Outer
package demoinnerclass;
class Outer{}//外部类
public class Test {
}
2.1静态内部类
1.在类中又定义了一个由static修饰的内部类叫做静态内部类(静态内部类用的最多)
代码
package demoinnerclass;
class Outer{
public int date1 = 1;
private int date2 = 2;
public static int date3 = 3 ;
static class interClass{
//静态内部类
}
}
public class Test {
}
2. 我们可以看到我们使用不了date1和date2,但是能够使用date3,date4,date5,date6
3.注意要点
(1)在静态内部类中是否能够直接访问外部类对象的非静态成员变量呢?
答案:不可以直接访问(注意是不能直接访问)
解析:因为外部类对象的成员依赖外部类对象
(2)如何在静态内部类访问外部类中的对象呢?
答案:通过在静态内部类中初始化外部类对象,再通过初始化的对象对外部类中的成员变量进行引用
(4)被stattic修饰的在外部类中可以被静态内部类中可以访问
(3)如何使用静态内部类(在代码注释部分以详细讲解)
代码
package demoinnerclass;
class Outer{
public int date1 = 1;
private int date2 = 2;
public static int date3 = 3 ;
static class interClass{
//静态内部类
public int date4 = 4;
public int date5 = 5;
public static int date6 = 6;
//也可以由构造方法
public void test(){
System.out.println("InnerClass::test()");
Outer outer = new Outer();
System.out.println(outer.date1);
System.out.println(outer.date2);
System.out.println(date3);
System.out.println(date4);
System.out.println(date5);
System.out.println(date6);
}
}
public void testFunc(){
System.out.println("Outer::testFunc()");
}
}
public class Test {
public static void main(String[] args) {
//如何获得静态内部类这个对象
//由于里面有一个静态内部类所以我们不能够初始化对象
//可以把静态内部类当作一个静态的成员可以通过调用的方式使用
Outer.interClass inn = new Outer.interClass();//格式//你看我是没有new这个对象的而是通过调用的方式
inn.test();//通过inn调用静态内部类中的test方法
}
}
(5)静态内部类也会生成字节码文件,组合方式是,外部类名$内部类类名class
3.实例内部类
1.1实例内部类概念
在外部类里再定义一个类,这个类没有被任何关键字修饰,那么这个类就是局部内部类
2.2实例内部类实现
代码
package demoinnerclass;
class OuterClass{
public int date1 = 1;
private int date2 = 2 ;
public static int data3 = 3;
class InnerClass{//实例内部类
public int date4 = 4;
private int date5 = 5;
//常量在编译的时候是确定的
public static final int data6 = 6;
public void test(){
}
}
}
public class Test {
public static void main(String[] args) {
// InnerClass innerClass = new OuterClass();//和静态内部类一样不能够直接调用
}
}
正确使用局部内部类是这样代码如下:有两种使用方式看你喜欢哪一个
package demoinnerclass;
class OuterClass{
public int date1 = 1;
private int date2 = 2 ;
public static int data3 = 3;
class InnerClass{//实例内部类
public int date4 = 4;
private int date5 = 5;
//常量在编译的时候是确定的
public static final int data6 = 6;
public void test(){
}
}
}
public class Test {
public static void main(String[] args) {
// InnerClass innerClass = new OuterClass();//和静态内部类一样不能够直接调用
OuterClass out = new OuterClass();//第一种
OuterClass.InnerClass innerClass = out.new InnerClass();
OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();//第二种
}
}
3.3使用局部内部类
代码
我们用了第一种方法来使用局部内部类,再通过调用innerClass中调用test方法,最后运行程序结果是:“实例内部类”
class OuterClass {
public int date1 = 1;
private int date2 = 2;
public static int data3 = 3;
class InnerClass {//实例内部类
public int date4 = 4;
private int date5 = 5;
//常量在编译的时候是确定的
public static final int data6 = 6;
public void test() {
System.out.println("实例内部类");
}
}
}
class Frank {
static class OuterClass {
public int date1 = 1;
private int date2 = 2;
public static final int data3 = 3;
class InnerClass {//实例内部类
public int date4 = 4;
private int date5 = 5;
//常量在编译的时候是确定的
public static final int data6 = 6;
public void test() {
System.out.println("实例内部类");
}
}
}
public static class Test {
public static void main(String[] args) {
OuterClass out = new OuterClass(); // 第一种
OuterClass.InnerClass innerClass = out.new InnerClass();
innerClass.test();
}
}
}
(1)所以可以看出静态内部类是比较好的相较于实例内部类,我不用再 实例化一次对象相较于局部内类,再静态内部类中我们是直接调用了InnerClass,而局部内部类却是new InnerClass。
(2)如果要定义static成员,我们记得要用final修饰。(将它变成一个常量)
(3)实例内部类中不能定义静态成员变量(包括静态常量)
(4)在运行的过程中优先访问内部类中的同名成员,如果我们想访问外部类,有两种方式,
第一种
实例化外部类对象,然后通过外部类对象访问这个同名成员变量
第二种
外部类类名+.this+.同名成员变量(同名的是date1)
System.out.println(OuterClass.this.date1);
可以理解为实例内部类中包含两个this,一个是外部类的this一个是实例内部类自己的this。(特殊记一下)
最终代码
class OuterClass {
public int date1 = 1;
private int date2 = 2;
public static final int data3 = 3;
public static final int data6 = 6;
//实例内部类
class InnerClass {
public int date4 = 4;
private int date5 = 5;
public void test() {
System.out.println("date1" + date1);
System.out.println("data2" + date2);
System.out.println("data3" + data3);
System.out.println("data4" + date4);
System.out.println("data5" + date5);
System.out.println("data6" + data6);
}
}
}
public class Frank {
public static void main(String[] args) {
OuterClass out = new OuterClass();
OuterClass.InnerClass innerClass = out.new InnerClass();
innerClass.test();
}
}
4.匿名内部类
4.1匿名对象
1.如果我们只使用一次这个对象那么我们就使用匿名对象。
代码如下
class Test{
public void func(){
System.out.println("func()");
};
}
public class Frank {
public static void main(String[] args) {
Test test = new Test();
test.func();
//只实例化了一个test对象
test.func();
System.out.println("//");
new Test().func();//匿名对象
// 实例化了两个test对象
new Test().func();//匿名对象
}
}
4.2匿名内部类
1.代码
interface InterfaceA{
void func();
}
class TestA implements InterfaceA{
@Override
public void func() {
System.out.println("我是重写的func方法");
}
}
class Test{
public void func(){
System.out.println("func()");
};
}
public class Frank {
public static void main(String[] args) {
Test test = new Test();
System.out.println("///");
InterfaceA a = new InterfaceA(){
@Override
public void func() {
System.out.println("哈哈,不懂了吧");
}
};
}
}
画红圈的就是匿名内部类。
2.可以理解为画红圈的部分是一个类实现了一个接口,并且重写了接口当中的
func()方法。
接口引用了一个对象。然后访问func()方法。
5.局部内部类(比较鸡肋)
5.1.概念
1.在一个类中的方法中定义一个类
2.只能在方法当中对这个类进行实例化(只能在方法内使用)
5.2注意事项
1.会生成字节码文件
2.不能被public static private 等修饰符修饰。
3.几乎不用!!!!!!!!!!!!!!!!几乎不用啊啊啊啊啊!!!!!!!