内部类浅谈

概念:

静态内部类的作用:只是为了降低包的深度,方便类的使用,实现高内聚。静态内部类适用于不依赖于外部类,不用使用外在类的非静态属性和方法,只是为了方便管理类结构而定义。在创建静态内部类的时候,不需要外部类对象的引用。非静态内部类有一个很大的优点:可以自由使用外部类的所有变量和方法,对其外部类有个引用
有了这两个区别,各位看官应该知道什么时候使用什么样的类了吧

下面是静态方法和非静态方法的区别:

静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存,不自动进行销毁,会一直存在于内存中,直到JVM关闭。静态方法的使用效率比非静态方法的效率高。静态方法是共享代码段,静态变量是共享数据段。既然是“共享”就有并发(Concurrence)的问题。

非静态方法(Non-Static Method)又叫实例化方法,属于实例对象,实例化后才会分配内存,必须通过类的实例来引用。不会常驻内存,当实例对象被JVM 回收之后,也跟着消失。是针对确定的一个对象的,所以不会存在线程安全的问题
静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别

适当地使用static方法本身并没有什么,当一个人从来不懂使用多态、接口设计时,很自然地会滥用static方法。

通常通用的类中一些常用的方法可以设计为静态的
只要是没有用到类的状态信息,只从参数获取信息的都可以为静态的
静态方法可以实现某些特殊的设计模式:如Singleton
由于没有this指针,可以把某些系统API的回调函数以静态函数的形式封装到类的内部
那么,匿名内部类有什么好处呢?除了只能使用一次,其实还有其他用处哦~
当你想使用一个类的protected 方法时,但是目前你的类又和他不同包且也不能继承他,这时候匿名类就派上用场了,你可以声明一个匿名类继承该类,并定义一个方法然后调用父类方法即可

使用场景

内部类和静态内部类的区别
静态类
只能在内部类中定义静态类
静态内部类不依赖于外部类,即使外部类没有创建对象,静态类也可以new对象
静态类的方法可以是静态的方法也可以是非静态的方法,静态的方法可以在外层通过静态类调用,而非静态的方法必须要创建类的对象之后才能调用。
静态类只能引用外部类的static成员变量(变量或者方法)(也就是类变量)。
如果一个内部类不是被定义成静态内部类,那么在定义成员变量或者成员方法的时候,是不能够被定义成静态的。(静态成员只能定义在静态内部类里)
和普通内部类的区别
是否能拥有静态成员
静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。
访问外部类的成员
静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。
静态内部类和非静态内部类在创建时有区别

说说内部类的好处吧

内部类可以很好的实现隐藏(一般的非内部类,是不允许有 private 与protected权限的,但内部类可以)
内部类拥有外围类的所有元素的访问权限
可以实现多重继承
可以避免修改接口而实现同一个类中***两种同名方法***的调用 **

Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类。内部类又分为:常规内部类、局部内部类、匿名内部类和静态嵌套类四种

一个文件里可以有多个类,但public的类只能有一个且必须和文件名一样。public final class可以这样写,但不能这样写:public static class A。但如果这个类是内部类,是可以这样写的:public static class A
在这里插入图片描述

1,最常见的内部类就是成员内部类,也称作普通内部类;

在这里插入图片描述
1、Inner类定义在Outer类的内部,相当于Outer类的成员变量的位置,Inner类可以使用任意访问修饰符,如:public、private、protected等。

2、Inner类中定义的test()方法可以访问Outer类中的数据,不受访问控制符的影响。
	
3、 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,
即:内部类 对象名 = 外部类对象.new 内部类( );如创建Inner的内部类对象:要先创建外部类对象:Outer o = new outer(); 创建内部类:Inner i = o.new Inner();访问Inner中的test()方法:i.test();

如果外部类和内部类具有相同的成员变量或方法,内部类可以直接访问内部类的成员变量或方法,但如果内部类访问外部类的成员变量或者方法时,需要使用this关键字;如下:

在这里插入图片描述

在上面的例子里我们可以清晰的看到:

内部类就像一个实例成员一样存在于外部类中。
内部类可以访问外部类的所有成员就想访问自己的成员一样没有限制。
内部类中的this指的是内部类的实例对象本身,如果要用外部类的实例对象就可以用类名.this的方式获得。
内部类对象中不能有静态成员,原因很简单,内部类的实例对象是外部类实例对象的一个成员。
下面我们再小结一下内部类的创建方法:

在外部类的内部,可以用 Inner inner = new Inner(); 方法直接创建
在外部类外部,必须先创建外部类实例,然后再创建内部类实例,
除了上面 Inner inner = new Outer().new Inner()的写法以外,
还有 Outer outer = new Outer(); Inner inner = outer.new Inner();的写法
静态内部类就是用static修饰的内部类,这种内部类的特点是:

方法内部类:

方法内部类就是定义在外部类的方法中,方法内部类只在该方法内可以用;
这时候我们称这个类叫局部内部类。
在这里插入图片描述

我们通过上面这里例子也可以看到下面几点:

局部内部类的地位和方法内的局部变量的位置类似,因此不能修饰局部变量的修饰符也不能修饰局部内部类,譬如public、private、protected、static、transient等

局部内部类只能在声明的方法内是可见的,因此定义局部内部类之后,想用的话就要在方法内直接实例化,记住这里顺序不能反了,一定是要先声明后使用,否则编译器会说找不到。

局部内部类不能访问定义它的方法内的局部变量,除非这个变量被定义为final 。

匿名内部类

当我们把内部类的定义和声明写到一起时,就不用给这个类起个类名而是直接使用了,这种形式的内部类根本就没有类名,因此我们叫它匿名内部类。
匿名内部类也就是没有名字的内部类

正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

注意:

匿名内部类不能定义任何静态成员、方法。

匿名内部类中的方法不能是抽象的;

匿名内部类必须实现接口或抽象父类的所有抽象方法。

匿名内部类访问的外部类成员变量或成员方法必须用static修饰;

代码:

接口

public interface Inner {
public String say();
}
抽象类

public abstract class Inner1 implements Inner {
}
普通类

public class Inner2 implements Inner {
public String say() {
return “this is Inner2”;
}
}

public class Outer {

    public static String s1 = "this is s1 in Outer";
    public static String s2 = "this is s2 in Outer";
    private static String s3 = "this is s3 in Outer";

    public void method1(Inner inner) {
        System.out.println(inner.say());
    }

    private static String method2() {
        return "this is method2 in Outer";
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        // 测试1,Inner为接口
        outer.method1(new Inner() {
            String s1 = "this is s1 in Inner";

            public String say() {
                // 外部类和匿名函数类中有同名变量s1
                return s1;
            }
        });
        // 测试2,Inner1为抽象类
        outer.method1(new Inner1() {
            String s2 = "this is s2 in Inner1";

            public String say() {
                // 外部类和匿名函数类中有同名变量s2
                return Outer.s2;
            }
        });
        // 测试3,Inner2为普通类
        outer.method1(new Inner2() {
            public String say() {
                // 访问外部类私有变量s3
                return s3;
            }
        });
        // 测试4,Inner2为普通类
        outer.method1(new Inner2() {
            public String say() {
                // 访问外部类私有方法method1()
                return method2();
            }
        });
    }
}

静态嵌套类

当一个内部类前面用static修饰时,我们称之为静态嵌套类或者说静态内部类。
因为静态嵌套类和其他静态方法一样只能访问其它静态的成员,而不能访问实例成员。因此静态嵌套类和外部类(封装类)之间的联系就很少了,他们之间可能也就是命名空间上的一些关联

package inner;

/**
* @author: Joho Woo
* @email: kongbowoo@163.com
* @version: 1.0 
* @time: 2007-11-12 下午07:52:29
* @description: 
*/
public class StaticTest
{
   private static String name = "woobo";
   private String num = "X001";

   static class Person
   {
     private String address = "China";
     public String mail = "kongbowoo@yahoo.com.cn";//内部类公有成员

     public void display()
     {
       //System.out.println(num);//不能直接访问外部类的非静态成员
       System.out.println(name);//只能直接访问外部类的静态成员
       System.out.println("Inner " + address);//访问本内部类成员。
     }
   }

   public void printInfo()
   {
     Person person = new Person();
     person.display();

     //System.out.println(mail);//不可访问
     //System.out.println(address);//不可访问

     System.out.println(person.address);//可以访问内部类的私有成员
     System.out.println(person.mail);//可以访问内部类的公有成员

   }

   public static void main(String[] args)
   {
     StaticTest staticTest = new StaticTest();
     staticTest.printInfo();
   }
}

在静态嵌套类内部, 不能访问外部类的非静态成员, 这是由Java语法中"静态方法不能直接访问非静态成员"所限定.若想访问外部类的变量, 必须通过其它方法解决, 由于这个原因, 静态嵌套类使用很少.

注意, 外部类访问内部类的的成员有些特别, 不能直接访问, 但可以通过内部类实例来访问, 这是因为静态嵌套内的所有成员和方法默认为静态的了.同时注意, 内部静态类Person只在类StaticTest 范围内可见, 若在其它类中引用或初始化, 均是错误的.

为何要用内部类?

1. 内部类一般只为其外部类使用;

2. 内部类提供了某种进入外部类的窗户;

3. 也是最吸引人的原因,每个内部类都能独立地继承一个接口,而无论外部类是否已经继承了某个接口。因此,内部类使多重继承的解决方案变得更加完整。

每日贴图

好好学习,好好赚钱娶媳妇

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值