java内部类之成员内部类、静态内部类

内部类其实就是一个类中还包含着另外一个类

如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液、跳动)显然,此处不能单方面用属性或者方法表示一个心脏,而需要一个类,而心脏又在人体当中,正如同是内部类在外部内当中

广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。

一、成员内部类:成员内部类是最普通的内部类,它的定义为位于另一个类的内部,成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

//外部类
class Out {
    private int age = 12;

    //内部类
    class In {
        public void print() {
            System.out.println(age);
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
        //或者采用下种方式访问
        /*
        Out out = new Out();
        Out.In in = out.new In();
        in.print();
        */
    }
}

运行结果:12

从上面的例子不难看出,内部类其实严重破坏了良好的代码结构,但为什么还要使用内部类呢?

因为内部类可以随意使用外部类的成员变量(包括私有)而不用生成外部类的对象,这也是内部类的唯一优点

如同心脏可以直接访问身体的血液,而不是通过医生来抽血

程序编译过后会产生两个.class文件,分别是Out.class和Out$In.class

其中$代表了上面程序中Out.In中的那个 .

Out.In in = new Out().new In()可以用来生成内部类的对象,这种方法存在两个小知识点需要注意

  1.开头的Out是为了标明需要生成的内部类对象在哪个外部类当中

  2.必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量

内部类中的变量访问形式:

class Out {
    private int age = 12;

    class In {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("局部变量:" + age);
            System.out.println("内部类变量:" + this.age);
            System.out.println("外部类变量:" + Out.this.age);
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
    }
}

运行结果:

局部变量:14

内部类变量:13

外部类变量:12

注意:

1、成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

2、当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量
外部类.this.成员方法

3、虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问

4、成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。

5、内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。由于成员内部类看起来像是外部类的一个成员,所以可以像类的成员一样拥有多种权限修饰。

二、静态内部类:静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象

public class Test {
    public static void main(String[] args)  {
        Outter.Inner inner = new Outter.Inner();
    }
}

class Outter {
    public Outter() {

    }

    static class Inner {
        public Inner() {

        }
    }
}

静态类的使用场景:

(1) 外部类需要使用内部类,而内部类无需使用外部类的资源

(2) 内部类可以独立外部类创建对象

使用静态内部类的好处是加强了代码的封装性以及提高了代码的可读性,举个例子:

public class Person{
     //姓名
     private String name;
     //家庭
     private Home home;
     //构造函数设置属性值
     public Person(String _name){
          name = _name;
     }
     /* home、name的getter/setter方法省略 */    

     public static class Home{
          //家庭地址
          private String address;
          //家庭电话
          private String tel;    

          public Home(String _address,String _tel){
            address = _address;
            tel = _tel;
          }
          /* address、tel的getter/setter方法省略 */
     }
}

把Home放在Person内部,一看便知道Home是Person的一个属性。使用的时候也很方便,如下代码:

public static void main(String[] args) {
    Home home = new Person.Home("上海", "021");
    Person p1 = new Person("张三");
    Person p2 = new Person("李四");
    p1.setHome(home);
    p2.setHome(home);
}   

这里创建一个home对象,p1和p2都使用这个home对象,p1和p2共享同一个home对象。

如果把Home换成普通内部类,情况就不同了,这时代码变成:

public static void main(String[] args) {
    Person p1 = new Person("张三");
    Home home = p1.new Home("上海", "021");
    p1.setHome(home);
    Person p2 = new Person("李四");
    p2.setHome(home);
} 

这里p1和p2依然共享同一个home对象,但此时home对象和p1是同生共死的,如果p1对象消亡,那么p2就没有

家了,这对p2来说实在不公平,而如果为p1和p2都创建一个Home对象,又浪费资源。所以在这个例子中,

使用静态内部类比普通内部类要合适。

静态内部类和普通内部类的区别

(1)普通内部类不能声明static的方法和变量

普通内部类不能声明static的方法和变量,注意这里说的是变量,常量(也就是final static修饰的属性)

还是可以的,而静态内部类形似外部类,没有任何限制。

(2)使用静态内部类,多个外部类的对象可以共享同一个内部类的对象。

使用普通内部类,每个外部类的对象都有自己的内部类对象,外部对象之间不能共享内部类的对象

时间: 2024-08-29 13:20:03

java内部类之成员内部类、静态内部类的相关文章

Java内部类:成员内部类(二)

Java内部类分为4个部分进行阐述,分别为概览.成员内部类.局部内部类和匿名内部类. 在本文中是Java内部类的成员内部类,主要讲述成员内部类的访问方式和一些细节. 成员内部类 成员内部类的访问方式 非static成员内部类 static成员内部类 外部类提供一个方法创建内部类的对象 直接创建内部类的对象 成员内部类要注意的细节 1.成员内部类的访问方式 成员内部类的访问方式,也可以理解为它的创建方式,主要分为两种:第一种是由外部类提供一个方法,用来创建内部类的对象,第二种方法直接创建内部类的对

Java内部类(4):静态内部类&接口内部类

使用static修饰的内部类我们称之为静态内部类,不过我们更喜欢称之为嵌套内部类.静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有.没有这个引用就意味着: 1. 它的创建是不需要依赖于外围类的. 2. 它不能使用任何外围类的非static成员变量和方法. 1 interface Contents { 2 int value(); 3 } 4 5 interface Destination {

java内部类之成员内部类

内部类概念:顾名思义,就是将一个类定义在另一个个类内部.内部的类称之为内部类 . 内部类的主要特点:1.内部类可以很好的实现隐藏,可以使用protected.private修饰符.2.内部类可以直接访问外部类的所有成员,包括私有成员.3.外部类不能直接访问内部类的成员,必须首先要建立内部类的对象才可以访问.4.内部类可以解决一些问题,比如间接地实现继承.可以避免修改接口而实现同一个类 中两种同名方法的调用 内部类有四种: 成员内部类,静态内部类,匿名内部类,局部内部类 起名字时,$符号是合法字符

java内部类之成员内部类实例

第一个是如何实现同时继承两个类 public class MultiExtendsDemo { public static void main(String[] args) { // TODO Auto-generated method stub C c = new C(); c.showA(); c.showB(); } } //同时继承两个类 class A{ public void showA() { System.out.println("A"); } } class B{ p

Java内部类小程序(成员内部类,静态内部类,匿名内部类)

1 /** 2 * 测试java内部类(成员内部类,静态内部类,匿名内部类) 3 * 局部内部类不常用,就不写了. 4 * @package :java05 5 * @author shaobn 6 * @Describe : 7 * @Time: 2015-9-6 下午8:32:38 8 */ 9 public class TestInner { 10 11 /** 12 * @author shaobn 13 * @Describe : 14 * @param args 15 * @Time

Java中的内部类(成员内部类、静态内部类、局部内部类、匿名内部类)

Java中的内部类(成员内部类.静态内部类.局部内部类.匿名内部类) 神话丿小王子的博客主页 我们先看这样一段话:人是由大脑.肢体.器官等身体结果组成.而组成我们人体的心脏它也有自己的属性和行为(血液.跳动),显然,此处不能单方面用属性或者方法表示一个心脏了,而需要一个类,但是这个类要依赖于人这个类存在(因为心脏不能脱离人体而存活,当然不考虑现今社会的发达科技,只从正常情况下来说),所心脏以需要写在人类的内部.内部类就相当于其中的某个器官之一. 首先看看什么是内部类:在类的内部定义另一个类.没错

浅谈java内部类

一.什么是内部类? 到底什么是内部类呢?通俗的讲,就是在类内部定义的类,包括定义在一个类的方法外面.方法里面或者代码块中. 二.为什么要使用内部类? 为什么我们要不走寻常路,把一个类定义在另一个类的内部呢?这样到底是出于什么目的呢?其实内部类是为了弥补java的单继承的特点,以实现多继承.内部类可以继承抽象类或实现接口.这样外部类也继承一个父类,就变相的实现了多继承.内部类可以访问外部类的属性,包括私有属性. 三.成员内部类 先上代码: package noStaticInnerClass; p

java 内部类的使用

内部类,将一个类A定义在另外一个类B的内部,那么我们就称类A为内部类 1.成员内部类 实验探究: 创建类Testpublic class Test { public static void main(String[] args) { } } 创建一个类Out代表外部类,一个类In代表内部类,在类中声明各种属性class Out {//java中并不推荐在命名中使用_来定义变量名和方法名,但为了表述直观,这里暂 且这么做. int out_a;//定义一个外部类成员变量 static int st

【转】Java 内部类种类及使用解析

Java 内部类种类及使用解析 内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Java中的内部类共分为四种: 静态内部类static inner class (also called nested class) 成员内部类member inner class 局部内部类local inner class 匿名内部类anonymous inner class 静态内部类Static