导航:首页 > 编程语言 > java内部类

java内部类

发布时间:2022-01-14 14:31:54

java中内部类

在java语言中,有一种类叫做内部类(inner class),也称为嵌入类(nested class),它是定义在其他类的内部。内部类作为其外部类的一个成员,与其他成员一样,可以直接访问其外部类的数据和方法。只不过相比较外部类只有public和默认的修饰符不同,内部类作为一个成员,可以被任意修饰符修饰。编译器在编译时,内部类的名称为OuterClass$InnerClass.class 。

1、内部类访问数据变量
当在某些时候,内部类中定义的变量与外部类中变量名称相同时,如何确保正确地访问每一个变量呢?

1.1在main中直接从外部类调用内部类的方法

class Outer
{
private int index = 10;
class Inner
{
private int index = 20;
void print()
{
int index = 30;
System.out.println(this); // the object created from the Inner
System.out.println(Outer.this); // the object created from the Outer
System.out.println(index); // output is 30
System.out.println(this.index); // output is 20
System.out.println(Outer.this.index); // output is 10
}
}

void print()
{
Inner inner = new Inner();//得到内部类的引用
inner.print();
}
}

class Test
{
public static void main(String[] args)
{
Outer outer = new Outer();
outer.print();
}
}
在这里内部类Inner中关键字this指向内部类Inner的对象,如果要想指向外部类的对象,必须在this指针前加上外部类名称,表示this是指向外部类构造的碎屑,如Outer.this 。

1.2在main中显式返回内部类引用

class Outer
{
private int index = 10;
class Inner
{
private int index = 20;
void print()
{
int index = 30;
System.out.println(index);
System.out.println(this.index);
System.out.println(Outer.this.index);
}
}

Inner getInner()
{
return new Inner();//返回一个内部类的引用
}
}

class Test
{
public static void main(String[] args)
{
Outer outer = new Outer();
Outer.Inner inner = outer.getInner();
inner.print();
}
}
Inner是Outer的内部类,所以在类Test中必须用属性引用符来标识出内部类。

1.3当main方法在Outer类内部

class Outer
{
private int index = 10;
class Inner
{
private int index = 20;
void print()
{
int index = 30;
System.out.println(index);
System.out.println(this.index);
System.out.println(Outer.this.index);
}
}

Inner getInner()
{
return new Inner();//返回一个内部类的引用
}

public static void main(String[] args)
{
Outer outer = new Outer();
Inner inner = outer.getInner(); // 注意此处变化
inner.print();
}
}
因为main方法在Outer内部,故可以直接引用,不需要属性引用符。

1.4在main方法中直接产生内部类对象

class Test
{
public static void main(String[] args)
{
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // 注意此处变化
inner.print();
}
}
在利用new构造方法构造一个外部类对象时,并没有连带着构造一个内部类对象,故需要访问内部类方法时,必须使用new操作符为这个外部类对象再构造一个内部类对象。

2、局部内部类
在方法中定义的内部类是局部内部类,它只能访问方法中的final类型的局部变量,因为用final定义的局部变量相当于是一个常量,延长了其生命周期,使得方法在消亡时,其内部类仍可以访问该变量。另外,它同样也可以引用定义在外部类的变量和方法。而且方法体中的局部内部类不允许有访问修饰符。

class Outer
{
int num=10;
public void print(final int aArgs)
{
class Inner
{
int num=20;
public Inner()
{
System.out.println("This is Inner.");//此句可看出它与匿名内部类用法的不同。
}

public void print()
{
int num=30;
System.out.println(this); // the object created from the local Inner
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
System.out.println(aArgs);
}
}
Inner inner=new Inner();//此句必须放在定义类Inner的后面
inner.print();
}

public static void main(String[] args)
{
Outer outer=new Outer();
outer.print(40);
}
}
对于局部类的命名,不管是在一个方法中定义多个类还是在几个方法中分别定义类,其编译后命名是:OuterClass$1InnerClass.class

3、匿名内部类
匿名内部类作为一种特殊的内部类,除了具有普通内部类的特点,还有自己的一些独有特性:
匿名内部类必须扩展一个基类或实现一个接口,但是不能有显式的extends和implements子句;
匿名内部类必须实现父类以及接口中的所有抽象方法;
匿名内部类总是使用父类的无参构造方法来创建实例。如果是实现了一个接口,则其构造方法是Object();
匿名内部类编译后的命名为:OuterClass$n.class,其中n是一个从1开始的整数,如果在一个类中定义了多个匿名内部类,则按照他们的出现顺序从1开始排号。

abstract class A
{
abstract public void sayHello();
}

class Outer
{
public static void main(String[] args)
{
new Outer().callInner(new A()
{
public void sayHello()
{
System.out.println(this); // the object created from the anonymous Inner
System.out.println("Hello!");
}
});
}

public void callInner(A a)
{
a.sayHello();
}
}

4、静态内部类
和非静态内部类相比,区别就在于静态内部类没有了指向外部类的引用。除此之外,在任何非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类(内部类的嵌套可以不止一层)。不过静态内部类中却可以拥有这一切。这也算是两者的第二个区别吧。一个静态的内部类,才可以声明一个static成员,静态内部类可以访问外围类的静态方法、成员(包括private static的成员)。静态内部类实例化的时候不必先实例化外围类,可以直接实例化内部类。而对于非静态内部类则必须先实例化其外部类,才能再实例化本身。

5.内部类的继承
当一个类继承自一个内部类时,缺省的构造器不可用。必须使用如下语法:
class WithInner
{
class Inner
{
public void sayHello()
{
System.out.println("Hello.");
}
}
}

public class Test extends WithInner.Inner
{
Test(WithInner wi)
{
wi.super();
}
public static void main(String[] args)
{
WithInner wi=new WithInner();
Test test=new Test(wi);
test.sayHello();
}
}
因为每一个内部类都有一个指向外部类的引用,在继承一个内部类,必须先创建一个外部类,通过这个外部类引用来调用其内部类的构造方法。如果继承的内部类是一个静态内部类,则就不需要这样,直接super()调用即可;

6、内部类的2种特殊用法
一个类从另一个类派生出来,又要实现一个接口。但在接口中定义的方法与父类中定义的方法的意义不同,则可以利用内部类来解决这个问题。
interface Machine
{
void run();
}

class Person
{
void run()
{
System.out.println("run");
}
}

class Robot extends Person
{
private class MachineHeart implements Machine
{
public void run()
{
System.out.println("heart run");
}
}

Machine getMachine()
{
return new MachineHeart();
}
}

class Test
{
public static void main(String[] args)
{
Robot robot = new Robot();
Machine m = robot.getMachine();
m.run();
robot.run();
}
}
在Robot类内部使用内部类MachineHeart来实现接口Machine的run方法。同时Robot类又继承了父类Person的run方法。如果不使用内部类MachineHeart而使Robot直接实现接口Machine,则该如何调用父类的run方法?

利用内部类可解决c++中多重继承所解决的问题
class A
{
void fn1()
{
System.out.println("It' s fn1.");
}
}

abstract class B
{
abstract void fn2();
}

class C extends A
{
B getB()
{
return new B()
{
public void fn2()
{
System.out.println("It' s fn2.");
}
};
}
}

class Test
{
public static void main(String[] args)
{
C c = new C();
c.fn1();
c.getB().fn2();
}
}
类C既要继承类A又要继承类B,则可将类B的定义放入类C内部,使之成为内部类。

一般情况下 当我们需要在某一情形下实现一个接口,而在另一情形下又不需要实现这个接口时,我们可以使用内部类来解决这一问题。让内部类来实现这个接口。另外一个很好的理由是java内部类加上接口可以有效地实现多重继承。

⑵ java的内部类有什么作用和特点

Java中的内部类共分为四种:
静态内部类static inner class (also called nested class)
成员内部类member inner class
局部内部类local inner class
匿名内部类anonymous inner class

静态内部类Static Inner Class
最简单的内部类形式。
类定义时加上static关键字。
不能和外部类有相同的名字。
被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。
只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
生成静态内部类对象的方式为:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
示例代码:
package com.learnjava.innerclass;
class StaticInner
{
private static int a = 4;
// 静态内部类
public static class Inner
{
public void test()
{
// 静态内部类可以访问外部类的静态成员
// 并且它只能访问静态的
System.out.println(a);
}
}
}
public class StaticInnerClassTest
{
public static void main(String[] args)
{
StaticInner.Inner inner = new StaticInner.Inner();
inner.test();
}
}

成员内部类Member Inner Class
成员内部类也是定义在另一个类中,但是定义时不用static修饰。
成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。
成员内部类就像一个实例变量。
它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
在外部类里面创建成员内部类的实例:
this.new Innerclass();
在外部类之外创建内部类的实例:
(new Outerclass()).new Innerclass();
在内部类里访问外部类的成员:
Outerclass.this.member
示例代码:
package com.learnjava.innerclass;
class MemberInner
{
private int d = 1;
private int a = 2;
// 定义一个成员内部类
public class Inner2
{
private int a = 8;
public void doSomething()
{
// 直接访问外部类对象
System.out.println(d);
System.out.println(a);// 直接访问a,则访问的是内部类里的a
// 如何访问到外部类里的a呢?
System.out.println(MemberInner.this.a);
}
}
}
public class MemberInnerClassTest
{
public static void main(String[] args)
{
// 创建成员内部类的对象
// 需要先创建外部类的实例
MemberInner.Inner2 inner = new MemberInner().new Inner2();
inner.doSomething();
}
}

局部内部类Local Inner Class
局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。
像局部变量一样,不能被public, protected, private和static修饰。
只能访问方法中定义的final类型的局部变量。
局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。
示例代码:
package com.learnjava.innerclass;
class LocalInner
{
int a = 1;
public void doSomething()
{
int b = 2;
final int c = 3;
// 定义一个局部内部类
class Inner3
{
public void test()
{
System.out.println("Hello World");
System.out.println(a);
// 不可以访问非final的局部变量
// error: Cannot refer to a non-final variable b inside an inner
// class defined in a different method
// System.out.println(b);
// 可以访问final变量
System.out.println(c);
}
}
// 创建局部内部类的实例并调用方法
new Inner3().test();
}
}
public class LocalInnerClassTest
{
public static void main(String[] args)
{
// 创建外部类对象
LocalInner inner = new LocalInner();
// 调用外部类的方法
inner.doSomething();
}

}

匿名内部类Anonymous Inner Class
匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。
匿名内部类隐式地继承了一个父类或者实现了一个接口。
匿名内部类使用得比较多,通常是作为一个方法参数。
生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。
示例代码:
package com.learnjava.innerclass;
import java.util.Date;
public class AnonymouseInnerClass
{
@SuppressWarnings("deprecation")
public String getDate(Date date)
{
return date.toLocaleString();
}
public static void main(String[] args)
{
AnonymouseInnerClass test = new AnonymouseInnerClass();
// 打印日期:
String str = test.getDate(new Date());
System.out.println(str);
System.out.println("----------------");
// 使用匿名内部类
String str2 = test.getDate(new Date()
{
});// 使用了花括号,但是不填入内容,执行结果和上面的完全一致
// 生成了一个继承了Date类的子类的对象
System.out.println(str2);
System.out.println("----------------");
// 使用匿名内部类,并且重写父类中的方法
String str3 = test.getDate(new Date()
{
// 重写父类中的方法
@Override
@Deprecated
public String toLocaleString()
{
return "Hello: " + super.toLocaleString();
}
});
System.out.println(str3);
}
}

⑶ 一个java内部类有几个分类

共有四种内部类,分别是:

1.常规内部类

2.静态内部类

3.局部内部类

4.匿名内部类

⑷ java程序中能否在内部类当中再定义一个内部类

我被你的想法震撼了,哈哈.亏你想的出来...这么弄代码不好理解,Java看起来醒目,也是Java中的一个规范!

可以吗?必须可以..看代码演示...声明下,我也第一次,多次嵌套,看你想法后去试验下是可行的

我用的两种办法!不多说看代码...

publicclass内部类
{
publicstaticvoidmain(String[]args)
{
System.out.println(" ==========java程序中能否在内部类当中再定义一个内部类?========== ");
init();
}//初始化!
privatestaticvoidinit()
{
newA().newB().newC().show();
newA().show();
}
}


classA
{
publicclassB
{
publicclassC
{
voidshow()
{
System.out.println("C类");
}
}
} voidshow()
{
newObject()
{
voidshow()
{
newObject()
{
voidshow()
{
System.out.println("我被搞昏头了!");
}
}.show();
}
}.show();
}
}

⑸ java内部类问题


你这个打印不了,因为你把内部类放在方法里面了,如果非要打印,可以考虑吧内部类放到类体里面,至于do的作用只是为了调用内部类的构造方法,因为你把构造方法改成需要一个String作为参数

publicclassb{
{
publicinnerclass2(Strings){
System.out.println(s);
}
}
publicOutInterfaceaction(Stringx){
returnnewinnerclass2("do");
}
publicstaticvoidmain(String[]args){
bd=newb();
d.action("123");
}
publicinterfaceOutInterface{
}
}



⑹ java中内部类的概念

简单的说,内部(inner)类指那些类定义代码被置于其它类定义中的类;而对于一般的、类定义代码不嵌套在其它类定义中的类,称为顶层(top-level)类。对于一个内部类,包含其定义代码的类称为它的外部(outer)类。 1 Static member class(静态成员类) 类声明中包含“static”关键字的内部类。如以下示例代码, Inner1/Inner2/Inner3/Inner4就是Outer的四个静态成员类。静态成员类的使用方式与一般顶层类的使用方式基本相同。
1内部类的嵌套可以理解成类的链关系,在构造一个内部类(非static)的实例的时候,会将直接外层类的实例
作为参数传进构造函数,而外层类的实例也是用其外层类的实例构造,所以是一种链状关系,内部的类可以使用所有
外层的类的实例,而外层的类不能使用内层的类, 应用a.this(最外层类实例) ,a.b.c.this(链中某个外层的实例)。

class TheOuter{
class kk {
class gg {
int tt = 100;
}
}

class aa {
class bb {
int jj = 10;
class cc {
{ int ff = TheOuter.aa.bb.this.jj;
// 无法直接访问到gg不在链关系内
System.out.println(ff);
}
}
}
}
}

2 创建一个内部类 new aa().new bb().new()cc 实际上是调用 外层类实例.new 本层构造函数()
如果内部类是static的不需要外层类的实例 多个static嵌套的内部类的实例 aa.bb.cc test = new aa.bb.cc();

3
class a0 {
class b0 {
}
}

class vvv{
class ff extends a0.b0 {// ff这里不是内部类也行
ff(a0 kk){
kk.super();
}
}
}
继承自内部类要调用父类的外层类的super()

4
class dd {
void print(){
System.out.println("dd.println is there");
}
class kk {
kk(int i){}
class cc {
void pp() {
System.out.println("****");
}
void ddpp() {
dd.this.print();
}
}
}
}

class aa {
public static void main (String agrs[]) {
dd.kk.cc test = new dd().new kk(10).new cc();
test.ddpp();
}
}
在类内部可以是使用外层类,但是如果生成一个实例的句柄就没有提供访问上层类的功能。

5 this 是指本类的实例

6 缺省的new
class cc {
{
new test();
}
class kk {
{
System.out.println("there kk");
}
}

class test {
{
new kk();
}
class kk {
{
System.out.println("there test_kk");
}
}
}
}
可以直接使用new,new的范围可以是 之际外层.this.new 和this.new 但是如果内层与外层出现同名类以内部优先

7
//当有链关系的时候要注意类不要重名
class vv {
class bb {} //!
class kk {
//class vv{} 这样就会出错
class bb {} //!这样就不会出错
}
}

8
class a0 {
class b0 {
}
}

class vvv{
class ff extends a0.b0 {// 不是内部类也行
ff(a0 kk){
kk.super();
}
}
}
继承自内部类要调用父类的外层类的super()

9 匿名内部类
interface oo {
//oo(int g) {}
int k = 10;
void pt();
}

class pp {
pp(int g) {
}
int get() {
return 100;
}
}

class me {
/*
interface oo {
void pt();
}
*/
class kk{
oo testmed() {
final int i = 10;
int g = 100;
return new oo() {
int kk;
{
// 使用外面的东西要声名成final
// 继承接口内部优先
// 匿名内部类没有构造函数,只能使用块,初始化
kk = i + k ;
}
public void pt() {
System.out.println(kk);
}
};
}
pp testmed0() {
return new pp(10){ // 继承自类
public int get() {
return super.get() * 10;
}
};
}
}
}
匿名内部类可以继承自接口也可以继承自类,继承自类的构造函数中 可以有参数。

10
class bf {
interface kk {}
class aa {
// 接口能嵌套在接口中(不受限制),或者嵌套在顶层,下面就不行
//interface gg {}
}
}

⑺ Java内部类的问题

你这个内部类是在method方法中定义的,就只能在这个方法中才能使用
在方法外面的时候相当于是没有这个内部类的
你报错的地方相当于在强转一个不存在的类,所以报错

⑻ 在Java中什么是内部类

内部类就是写在类中或方法中的类,它还是一个类,与其他类的不同就是他只为这个外部类(包含内部类的类)类所用

⑼ java内部类怎么使用

1.内部类的方法可以访问它所在的外部类中的所有域,包括私有型别的;
2.对于同一个包中的其它类它是隐藏的;
3. 匿名的内部类可以让我们很方便的定义事件响应(call back),这在GUI编程中很常见
interface OutInterface{ //定义一个接口 public void f(); } public class InterfaceInner { //主类 public static void main(String args[]){ OuterClass2 out=new OuterClass2(); OutInterface outinter=out.doit(); outinter.f(); } } class OuterClass2{ //定义一个内部类,并且接口OutInterface private class InnerClass implements OutInterface{ InnerClass(String s){ System.out.println(s); } public void f(){ System.out.println("访问内部类中的f()方法"); } } public OutInterface doit(){ //方法返回接口 return new InnerClass("访问内部类构造方法"); } }

⑽ 什么是内部类内部类有什么作用(java)

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。

成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:

class Circle { double radius = 0; public Circle(double radius) { this.radius = radius; } class Draw { //内部类 public void drawSahpe() { System.out.println("drawshape"); } }}

这样看起来,类Draw像是类Circle的一个成员,Circle称为外部类。成员内部类可以无条件访

class Circle { private double radius = 0; public static int count =1; public Circle(double radius) { this.radius = radius; } class Draw { //内部类 public void drawSahpe() { System.out.println(radius); //外部类的private成员 System.out.println(count); //外部类的静态成员 } }}

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

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

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

class Circle { private double radius = 0; public Circle(double radius) { this.radius = radius; getDrawInstance().drawSahpe(); //必须先创建成员内部类的对象,再进行访问 } private Draw getDrawInstance() { return new Draw(); } class Draw { //内部类 public void drawSahpe() { System.out.println(radius); //外部类的private成员 } }}

成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:
public class Test { public static void main(String[] args) { //第一种方式: Outter outter = new Outter(); Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建 //第二种方式: Outter.Inner inner1 = outter.getInnerInstance(); }} class Outter { private Inner inner = null; public Outter() { } public Inner getInnerInstance() { if(inner == null) inner = new Inner(); return inner; } class Inner { public Inner() { } }}

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

阅读全文

与java内部类相关的资料

热点内容
单片机中断的原理 浏览:892
php开源架构 浏览:578
最好听的解压声控 浏览:259
mdb2php 浏览:34
安卓怎么修改ini文件夹 浏览:926
机构投资的创新之路pdf 浏览:683
如何用路由器访问公司服务器 浏览:526
dosrd命令 浏览:678
玩子君手作解压丸子 浏览:252
php上传php文件出错 浏览:688
群晖盘阵建ftp子文件夹 浏览:546
天空都市服务器地址 浏览:433
c游戏编程入门教程pdf 浏览:672
php框架安全 浏览:715
梦里和程序员谈恋爱 浏览:175
特价服务器什么意思 浏览:379
程序员交接不想接怎么办 浏览:873
vb文件夹怎么选择 浏览:118
公众号验证码登陆源码 浏览:524
居民楼用电量与电缆算法 浏览:357