Java中内部类综合分析

内部类

1.成员内部类

成员内部类又称普通内部类,这是Java之中最常见的内部类
看如下代码:

public class Outer {
    private int a = 10;
    //int c = b;    //将会报错,b为未识别标识符,说明外部类不能访问内部类私有属性
    class Inner {
        private int b = 5;
        public void print() {
            System.out.println("访问外部类私有属性a:"+ a);
        }
    }

    public static void main(String[] args) {
        //Inner in = new Inner();     //这条语句将会报错
        Inner in = new Outer().new Inner();
        in.print();

    }
}

代码输出为:

访问外部类私有属性a:10

可以总结如下:
1.成员内部类可以访问外部类的私有属性

2.内部类可以使用任何修饰符,当使用private修饰内部类时,可以体现出封装性

3.定义了内部类成员后,(非静态内部类)必须通过外部类对象来创建内部类对象,不能直接去new一个内部类对象,正确的格式为:Inner inner = new Outer( ) . new Inner( ) ;

4.切记:外部内不能够直接访问内部类的成员和方法,必须通过创建内部类对象来进行访问;相反的是,内部类可以访问外部类的所有属性

5.成员内部类不能够拥有任何static变量和方法; 但可以访问外部类的静态域;
(分析原因:如果成员内部类拥有了static属性,那么其他类可以直接通过内部类名.属性就可以直接调用,但成员内部类的访问必须依赖于外部类,所以矛盾了)

6.使用内部类可以实现多继承 ,从而避免了Java单继承的缺陷;(代码如下)

class A {
    private int age = 20;
    public int getAge() {    //age为私有属性,则提供方法为外界提取age的值,所以为public
        return age;
    }
}
class B {
    private String name = "yy";
    public String getName() {
        return name;
    }
}
public class Outer {
    private class InnerA extends A{   //将这两个类设置为private权限是为了更好的封装;
        public int getAge() {
            return super.getAge();  //不能直接 return super.age  ,因为就算继承了父类,但也不能直接访问父类的私有属性;
        }
    }
    private class InnerB extends B {
        public String getName() {
            return super.getName();
        }
    }
    public int getAge() {
        return new InnerA().getAge();    //除了static属性和方法,其他方法在类外都得通过对象来调用
    }
    public String getName() {
        return new InnerB().getName();
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println("Outer类的age为:"+ outer.getAge());
        System.out.println("Outer类的name为:"+outer.getName());
    }
}

2.静态内部类

所谓静态内部类,就是用static关键字修饰的内部类;可以总结如下:

静态内部类与非静态内部类的最大区别:
非静态内部类在编译完成之后会隐含的保存着一个引用,该引用指向创建它的外围类,但是静态内部类却没有;
没有这个引用才导致静态内部类的创建不依赖于外部类;

1.静态内部类不能直接访问外部类的非静态成员,但可以通过new 外部类( ).成员来进行访问;

2、 如果外部类的静态成员与内部类的成员名称相同 ,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“**成员名”**直接调用外部类的静态成员。

3、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();

练习代码:

public class Outer {
    static int outStatic = 1;
    static int sstatic = 20;
    private int outerPri = 2;
    static class Inner {
        static int sstatic = 10;
        public void print() {
            System.out.println("外部类的静态成员可以直接访问:"+outStatic);  //1
            //System.out.println("不能直接访问外部类的非静态成员:"+outerPri);  //将会报错
            System.out.println("通过this关键字调用内部类与外部类同名属性为:"+this.sstatic);   //10
            System.out.println(("外部的同名属性为:"+Outer.sstatic));  //20

        }
    }

    public static void main(String[] args) {
        Inner in = new Inner();   //不用以来外部对象来生成内部类对象
        in.print();
        System.out.println(Inner.sstatic);  //静态属性可直接调用
    }
}

运行结果:

外部类的静态成员可以直接访问:1
访问外部类的非静态成员:2
通过this关键字调用内部类与外部类同名属性为:10
外部的同名属性为:20
10

3.方法内部类

方法内部类又称局部内部类,方法内部类与成员内部类基本一致,只是他们的作用域不相同,具体特点如下:

1.方法内部类只能在该方法中被使用,出了该方法就无效;

2.方法内部类不允许使用访问权限修饰符 public、private、protected均不允许;

3.方法内部类对外完全隐藏,除了创建这个类的方法可以访问它,其他的地方是不允许访问的

4.方法内部类要想使用该方法的形参,则可以直接使用(jdk8以后,现在基本都是jdk8以后了),jdk8以前该形参必须用final声名;

练习代码为:

class OuterA {
    private int a;
    public void print(int num) {
        class Inner {
            public void fun() {
                System.out.println(a);   //这个a就是上面的a
                System.out.println(num);  //打印形参
            }
        }
        new Inner().fun();
    }
}
public class Outer {
    public static void main(String[] args) {
        OuterA out = new OuterA();
        out.print(20);
    }
}

输出为:

0
20

4.匿名内部类

实质上匿名内部类就是一个没有名字的方法内部类,所以它符合方法内部类的所有约束,其他特点如下:

假如要执行的任务需要一个对象,但却不值得创建全新的对象(原因可能 是所需的类过于简单,或是由于他只在一个方法内部使用),匿名类就显得很有用。匿名类尤其适合在Swing应用程式中快速创建事件处理程式。

1.匿名内部类没有访问权限修饰符;

2.匿名内部类必须继承一个抽象类或者实现一个接口

3.匿名内中不能存在任何static修饰的属性与方法;

4.匿名内部类没有构造方法,因为他没有类名嘛;

练习代码如下:

interface Inter {
    void test();
}
class OuterA {
    private int a = 10;
    public void print(int num) {
        new Inter() {
            public void test() {
                System.out.println("匿名内部类:"+num);
            }
        }.test();
    }
}
public class Outer {
    public static void main(String[] args) {
        OuterA out = new OuterA();
        out.print(20);
        
    }
}

输出:
0
20

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值