【Java基础】java内部类使用场景

2021-01-29 21:04发布

7条回答
十七
2楼 · 2021-02-01 15:51

java中内部类使用更多的场景是匿名内部类,在继承或者实现关系中相当于一个对象,无需再创建子类或者实现类。

普通的内部类使用较少,更多是单独写一个实体类,然后在类中的成员变量定义实体类对象。


想减肥的小徐
3楼 · 2021-02-01 16:07

内部类分为成员内部类,局部内部类,静态内部类和匿名内部类.

成员内部类:

    当某个类除了他的外部类,不会被其他类使用时,使用成员内部类。这种情况下,内部类依附于外部类而存在,原因可能有: 1. 不可能有其他类使用该内部类。 2. 该内部类不能被其他类使用,可能会导致错误。这是内部类使用比较多的一个场景。

局部内部类:

    局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。局部内部类就像方法里面的局部变量一样,是不能有public、protected、private及static修饰符的。

静态内部类:

    静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,它不持有指向外部类对象的引用this,并且它不能使用外部类的非static成员或方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体对象。它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生。

匿名内部类:

    匿名内部类应该是平时我们编写代码时用的最多的,在编写事件监听的代码时匿名内部类不但方便,而且使代码更加容易维护。匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。

我自己打call
4楼 · 2021-02-02 09:39

所谓内部类,即定义在另一个类中的类。那么,为什么会有内部类这个概念,他的使用场景又是什么呢?
首先,来看一下内部类的特点:

1. 它体现了一种代码的隐藏机制和访问控制机制,内部类与所在外部类有一定的关系,往往只有该外部类调用此内部类,所以没有必要专门用一个Java文件存放这个类。

public class Outer {  private int num; 
  private class Inner {    private int num;
  }
}

一般的类是不允许用private修饰符的,但是内部类却可以,该实例中,类Inner只对Outer可见,其他的类无法访问的到Inner类。

注意,这里有个例外,如果内部类的访问修饰符被设定为public,那么它是可以被其他类使用的,但是必须经由外部类来实例化内部类。

复制代码

public class Outer {    private int num = 1;    public class Inner {        private int num = 2;
    }    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.new Inner();
        System.out.println(inner.num);
    }
}

复制代码

2. 它包含有一个对外部类的this指针,从而可以访问外部类的所有元素,包括所有public/private的成员和方法

复制代码

public class Outer {    private int num = 1;    public class Inner {        private int num = 2;        private void func () {
            System.out.println(Outer.this.num);
        }
    }    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.new Inner();
        inner.func();
    }
}

复制代码

另一方面,反向的,外部类对内部类的所有元素也都有访问权,包括内部类的私有成员和方法:

复制代码

public class Outer {    private int num = 1;    public class Inner {        private int num = 2;
    }    public void func () {
        Inner inner = new Inner();
        System.out.println(inner.num);
    }    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.func();    // 2
    }
}

复制代码

 

分类:

一、成员内部类

当某个类除了他的外部类,不会被其他类使用时,使用成员内部类。这种情况下,内部类依附于外部类而存在,原因可能有: 1. 不可能有其他类使用该内部类。 2. 该内部类不能被其他类使用,可能会导致错误。这是内部类使用比较多的一个场景。

1) 外部类可以直接访问内部类的成员和方法,但是必须先创建一个内部类的对象,再通过该对象使用其成员和方法。

2) 内部类可以访问外部类的成员和方法,但是要注意,当内部类拥有和外部类相同的成员或方法时,会发生隐藏现象,默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式访问:外部类.this.成员变量/方法

3) 内部类只是一个编译时的概念,一旦编译成功,就会成为完全不同的两个类。对于一个名为Outer的外部类和其内部定义的名为Inner的内部类,编译完后会生成Outer.class和Outer$Inner.class两个类

4) 成员内部类与普通的成员没什么区别,可以与普通成员一样进行修饰和限制

复制代码

public class Outer {    private int num = 1;    private int num1 = 10;    public class Inner {        private int num = 2;        public void func () {
            System.out.println(Outer.this.num);
            System.out.println(num1);
        }
    }    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.new Inner();
        inner.func();
    }
}

复制代码

 

二、局部内部类

 局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。局部内部类就像方法里面的局部变量一样,是不能有public、protected、private及static修饰符的。

复制代码

public class Outer {    private int num = 1;    private int num1 = 10;    public void func () {        class Inner {            private int num = 2;
        }
        Inner inner = new Inner();
        System.out.println(inner.num);
    }    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.func();
    }
}

复制代码

 

三、静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,它不持有指向外部类对象的引用this,并且它不能使用外部类的非static成员或方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体对象。它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生。

复制代码

public class Outer {    static class Inner {        public Inner () {

        }
    }    public static void main(String[] args) {
        Outer.Inner innner = new Outer.Inner();
    }
}

复制代码

 

 

四、匿名内部类

匿名内部类应该是平时我们编写代码时用的最多的,在编写事件监听的代码时匿名内部类不但方便,而且使代码更加容易维护。匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outer$1.class。一般来说,匿名内部类用于集成其他类或者实现接口,并不需要增加额外的方法,只是对集成方法的实现或是重写。

复制代码

public class Outer {    public void func () {
        System.out.println("1");
    }    public static void main(String[] args) {
        Outer inner = new Outer() {            public void func () {
                System.out.println("2");
            }
        };
        inner.func();
    }
}

复制代码


总结:

1. 每个内部类都能独立的集成一个接口的实现,所以无论外部类是否已经集成了某个(接口)实现,对于内部类都没有影响。内部类使得多重集成的解决方案变得完整。

2. 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

3. 方便编写时间驱动程序。

4. 方便编写线程代码。


20200921文 - 做更棒的自己!
5楼 · 2021-02-02 11:01

这个类作为外部类的一个属性....

比如说
类一:封装了工作信息
类二:封装了家庭信息

那么你要定义一个类 表示人的时候
前两个类就可以作为内部类....
当然这其中还牵涉到作用权限的问题........

studentaaa
6楼 · 2021-02-02 14:20

谓内部类,即定义在另一个类中的类。那么,为什么会有内部类这个概念,他的使用场景又是什么呢?
首先,来看一下内部类的特点:

1. 它体现了一种代码的隐藏机制和访问控制机制,内部类与所在外部类有一定的关系,往往只有该外部类调用此内部类,所以没有必要专门用一个Java文件存放这个类。

public class Outer {  private int num; 
  private class Inner {    private int num;
  }
}

一般的类是不允许用private修饰符的,但是内部类却可以,该实例中,类Inner只对Outer可见,其他的类无法访问的到Inner类。

注意,这里有个例外,如果内部类的访问修饰符被设定为public,那么它是可以被其他类使用的,但是必须经由外部类来实例化内部类。


public class Outer {    private int num = 1;    public class Inner {        private int num = 2;
   }    public static void main(String[] args) {
       Outer outer = new Outer();
       Inner inner = outer.new Inner();
       System.out.println(inner.num);
   }
}


2. 它包含有一个对外部类的this指针,从而可以访问外部类的所有元素,包括所有public/private的成员和方法


public class Outer {    private int num = 1;    public class Inner {        private int num = 2;        private void func () {
           System.out.println(Outer.this.num);
       }
   }    public static void main(String[] args) {
       Outer outer = new Outer();
       Inner inner = outer.new Inner();
       inner.func();
   }
}


另一方面,反向的,外部类对内部类的所有元素也都有访问权,包括内部类的私有成员和方法:


public class Outer {    private int num = 1;    public class Inner {        private int num = 2;
   }    public void func () {
       Inner inner = new Inner();
       System.out.println(inner.num);
   }    public static void main(String[] args) {
       Outer outer = new Outer();
       outer.func();    // 2
   }
}


 

分类:

一、成员内部类

当某个类除了他的外部类,不会被其他类使用时,使用成员内部类。这种情况下,内部类依附于外部类而存在,原因可能有: 1. 不可能有其他类使用该内部类。 2. 该内部类不能被其他类使用,可能会导致错误。这是内部类使用比较多的一个场景。

1) 外部类可以直接访问内部类的成员和方法,但是必须先创建一个内部类的对象,再通过该对象使用其成员和方法。

2) 内部类可以访问外部类的成员和方法,但是要注意,当内部类拥有和外部类相同的成员或方法时,会发生隐藏现象,默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式访问:外部类.this.成员变量/方法

3) 内部类只是一个编译时的概念,一旦编译成功,就会成为完全不同的两个类。对于一个名为Outer的外部类和其内部定义的名为Inner的内部类,编译完后会生成Outer.class和Outer$Inner.class两个类

4) 成员内部类与普通的成员没什么区别,可以与普通成员一样进行修饰和限制


public class Outer {    private int num = 1;    private int num1 = 10;    public class Inner {        private int num = 2;        public void func () {
           System.out.println(Outer.this.num);
           System.out.println(num1);
       }
   }    public static void main(String[] args) {
       Outer outer = new Outer();
       Inner inner = outer.new Inner();
       inner.func();
   }
}


 

二、局部内部类

 局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。局部内部类就像方法里面的局部变量一样,是不能有public、protected、private及static修饰符的。


public class Outer {    private int num = 1;    private int num1 = 10;    public void func () {        class Inner {            private int num = 2;
       }
       Inner inner = new Inner();
       System.out.println(inner.num);
   }    public static void main(String[] args) {
       Outer outer = new Outer();
       outer.func();
   }
}


 

三、静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,它不持有指向外部类对象的引用this,并且它不能使用外部类的非static成员或方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体对象。它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生。


public class Outer {    static class Inner {        public Inner () {

       }
   }    public static void main(String[] args) {
       Outer.Inner innner = new Outer.Inner();
   }
}


 

 

四、匿名内部类

匿名内部类应该是平时我们编写代码时用的最多的,在编写事件监听的代码时匿名内部类不但方便,而且使代码更加容易维护。匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outer$1.class。一般来说,匿名内部类用于集成其他类或者实现接口,并不需要增加额外的方法,只是对集成方法的实现或是重写。


public class Outer {    public void func () {
       System.out.println("1");
   }    public static void main(String[] args) {
       Outer inner = new Outer() {            public void func () {
               System.out.println("2");
           }
       };
       inner.func();
   }
}



总结:

1. 每个内部类都能独立的集成一个接口的实现,所以无论外部类是否已经集成了某个(接口)实现,对于内部类都没有影响。内部类使得多重集成的解决方案变得完整。

2. 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

3. 方便编写时间驱动程序。

4. 方便编写线程代码。

pipi雪
7楼 · 2021-02-03 11:24

java中内部类使用更多的场景是匿名内部类,在继承或者实现关系中相当于一个对象,无需再创建子类或者实现类。

普通的内部类使用较少,更多是单独写一个实体类,然后在类中的成员变量定义实体类对象。



寂静的枫林
8楼 · 2021-07-30 16:38

java中内部类使用更多的场景是匿名内部类,在继承或者实现关系中相当于一个对象,无需再创建子类或者实现类。

普通的内部类使用较少,更多是单独写一个实体类,然后在类中的成员变量定义实体类对象。


相关问题推荐

  • 回答 156

    对于每一位才开始接触JAVA的新手来说,先不要管算法和数据结构,大多数简单的程序不需要用到算法和数据结构,所以当你真正需要时再去学习。编程一段时间以后,你就会知道在哪些地方用到他们。这时知道算法的名字并了解它们的功能,然后动手去实践。当我们在去...

  • 回答 93

    2个都很好就业,更关键的是要学得到东西

  • 回答 12
    已采纳

    获取Map集合中所有的key可以通过map集合的keySet()方法获取例如:    Map map = new HashMap();    map.put(xx,xx); //存放数据    //.... 省略    Set set = map.keySet();    //可以通过迭代器进行测试    Iterator iter = set.iter...

  • 回答 56
    已采纳

    不同年龄,不同掌握程度,学历,找工作城市,面试能力这是一个多方面影响的结果,如果是平均值的话,全国平均薪资14k左右

  • 回答 38

    具体学多久,根据自己的学习力,自律性、解决问题能力来决定若系统性学习,跟着讲师的节奏走,大概半年左右,有专业的讲师把课程进行规划,尽心系统学习,有问题,讲师会帮忙解决,学习的效率很高,避免了自学中出现各种问题解决不了,而耽误很多时间,可能会...

  • 回答 23
    已采纳

    (1)idea启动时会有两个快捷方式,安装完后默认生成在桌面的是32位的idea的快捷方式,如果我们使用这个快捷方式运行大项目,一般都会很卡。解决方法是找到idea的安装目录,然后进入bin文件夹,找到名称为idea64的应用程序,右键他生成桌面快捷方式。以后每次...

  • BIO与NIO、AIO的区别2020-05-19 15:59
    回答 4
    已采纳

    IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。一、BIO     在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要...

  • Java方法的命名规则2021-04-06 19:07
    回答 31

    ava是一种区分字母的大小写的语言,所以我们在定义变量名的时候应该注意区分大小写的使用和一些规范,接下来我们简单的来讲讲Java语言中包、类、变量等的命名规范。(一)Package(包)的命名Package的名字应该都是由一个小写单词组成,例如com、xuetang9、compan...

  • 回答 2

    public class Point {    private int x;    private int y;    public int getX() {        return x;    }    public void setX(int x) {        this.x = x;    }    public int getY() {        return y;    } ...

  • 回答 6

    经典版单例模式public class Singleton {        private static Singleton uniqueInstance;//利用一个静态常量来记录singleton类的唯一实例。     private Singleton() {     }     public static  Singleton getInstance()...

  • 回答 3

    哈希表的长度一般是定长的,在存储数据之前我们应该知道我们存储的数据规模是多大,应该尽可能地避免频繁地让哈希表扩容。但是如果设计的太大,那么就会浪费空间,因为我们跟不用不到那么大的空间来存储我们当前的数据规模;如果设计的太小,那么就会很容易发...

  • 回答 14

    1. DOM(Document Object Model)        DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才...

  • 回答 19

    1)作用不同: throw用于程序员自行产生并抛出异常; throws用于声明在该方法内抛出了异常2) 使用的位置不同: throw位于方法体内部,可以作为单独语句使用; throws必须跟在方法参数列表的后面,不能单独使用。3)内容不同: throw抛出一个异常对象,且只能是...

  • 回答 11

    基本执行过程如下:1)程序首先执行可能发生异常的try语句块。2)如果try语句没有出现异常则执行完后跳至finally语句块执行;3)如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。4)catch语句块可以有多个,分别捕获不同类型...

  • 回答 20

    100-199 用于指定客户端应相应的某些动作。 200-299 用于表示请求成功。 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 400-499 用于指出客户端的错误。 400 语义有误,当前请求无法被服务器理解。 401 当前请求需要用户验证...

  • 回答 16

    异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译...

没有解决我的问题,去提问