今天就讲一下java的内部类:内部类顾名思义就是定义于一个public类中的类,内部类可以作为这个public的成员变量,可以由private和protected修饰,可以定义在一个public类的方法中。
首先来看一下内部类的用法:
package com.djk.neibuclass;
public class ClassTest
{
public static void main(String[] args)
{
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();
inner.say();
}
}
/**
* 外部类
* @author djk
*
*/
class Outter
{
class Inner
{
public void say()
{
System.out.println("我是内部类");
}
}
}
这是生成了一个内部实例,要生成非静态的内部类实例首先要生产外部类的实例,因为内部类中隐藏了一个指向外部类的一个引用,正是这个引用而让内部类访问外部类中的任意方法或属性包括私有的,下面举个列子:
package com.djk.neibuclass;
public class ClassTest
{
public static void main(String[] args)
{
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();
inner.say();
}
}
/**
* 外部类
* @author djk
*
*/
class Outter
{
private int i = 0;
class Inner
{
public void say()
{
System.out.println(i);
}
}
}
正如上面代码显示打印出来了外部类中的私有属性i。
package com.djk.neibuclass;
public class ClassTest
{
public static void main(String[] args)
{
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();
inner.say();
}
}
/**
* 外部类
* @author djk
*
*/
class Outter
{
private int i = 0;
class Inner
{
private int i =1;
public void say()
{
System.out.println(i);
}
}
}
这种情况有时也可能遇到就是外部类中有个属性i和内部类中的属性i名称一样,然后直接在内部类中调用i,此时打印的结果是内部类的i,如果想要用外部类的i则改成:
package com.djk.neibuclass;
public class ClassTest
{
public static void main(String[] args)
{
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();
inner.say();
}
}
/**
* 外部类
* @author djk
*
*/
class Outter
{
private int i = 0;
class Inner
{
private int i =1;
public void say()
{
System.out.println(Outter.this.i);
}
}
}
即可。
使用内部类的好处个人总结了3点
1,可以隐藏接口的实现:
package com.djk.neibuclass;
public class ClassTest2
{
public static void main(String[] args)
{
Man man =new Man();
man.buySomething();
}
}
/**
* 接口
* @author djk
*
*/
interface Action
{
void buySomething();
}
class Man
{
private class inner implements Action
{
public void buySomething()
{
System.out.println("买东西");
}
}
public void buySomething()
{
new inner().buySomething();
}
}
这里我们有个Action接口,里面定义了买东西的方法。此时我们的Man类要实现Action这个接口,可是又不想让别人看到是怎么实现的,这里就可以借助内部类来实现,Man类对外公开了一个方法,这个方法里其实是用内部类对象来调用了买东西的方法,这个内部类来实现了Action接口,而且因为这个内部类对外界是private所以是隐藏的看不见的。
2.实现多继承:
在java中一个类只能同时继承一个类不能同时继承2个类,可是有时我们一个类就是想继承2个类用里面的某些方法这是就可以用到内部类来完成:
package com.djk.neibuclass;
public class ClassTest3
{
public static void main(String[] args)
{
C c = new C();
c.say();
c.speak();
}
}
abstract class A
{
public abstract void say();
}
abstract class B
{
public abstract void speak();
}
class C
{
private class InnerClassA extends A
{
@Override
public void say()
{
System.out.println("a");
}
}
private class InnnerClassB extends B
{
@Override
public void speak()
{
System.out.println("b");
}
}
public void say()
{
new InnerClassA().say();
}
public void speak()
{
new InnnerClassB().speak();
}
}
此时的C借助与内部类即拥有了A的方法又拥有了C的方法。
3:有时当我们想要继承一个接口的时候发现接口中有个方法和本身中的一个方法重复了,可是又不想把本身的方法给覆盖了这是就可以利用内部类来完成这个需求:
package com.djk.neibuclass;
/**
* 这个类本身中有个go方法,可是要实现的接口中也有go方法,为了区分这2个go方法,就可以使用Inner内部类来实现Go接口实现Go方法。
* @author djk
*相关联系类:GO,ClassGoMain
*/
public class ClassGo
{
public void go()
{
System.out.println("这是我本身的GO哦");
}
private class Inner implements Go
{
public void go()
{
System.out.println("这是接口中的Go哦");
}
}
public void interfaceGo(){
new Inner().go();
}
}
package com.djk.neibuclass;
public interface Go
{
void go();
}
接下来讲一下匿名内部类:
package com.djk.neibuclass;
public class ClassTest4
{
public static void main(String[] args)
{
Move move = CarFactory.getMove();
move.go();
}
}
interface Move
{
void go();
}
class CarFactory
{
public static Move getMove()
{
return new Move()
{
public void go() {
System.out.println("汽车go");
}
};
}
}
这就是一个匿名内部类的列子。
在我的设计模式的文章中我写了一个抽象工厂模式,现在我们用匿名内部类来改写下这个抽象工厂:
package com.djk.neibuclass;
/**
* 抽象工厂方法
* @author djk
*
*/
public class FactoryTest4
{
public static void service(FactoryInterFace face)
{
Graphical1 g = face.getObject();
g.sayName();
}
public static void main(String[] args)
{
service(Triangle1.factory);
service(Square1.factory);
}
}
/**
* 抽象工厂定义
* @author djk
*
*/
interface FactoryInterFace
{
Graphical1 getObject();
}
/**
* 图形接口
* @author djk
*
*/
interface Graphical1
{
void sayName();
}
/**
* 三角形
* @author djk
*
*/
class Triangle1 implements Graphical1
{
private Triangle1()
{
}
public void sayName()
{
System.out.println("三角形");
}
public static FactoryInterFace factory = new FactoryInterFace()
{
public Graphical1 getObject()
{
return new Triangle1();
}
};
}
/**
* 正方形
* @author djk
*
*/
class Square1 implements Graphical1
{
private Square1 ()
{
}
public void sayName()
{
System.out.println("正方形");
}
public static FactoryInterFace factory = new FactoryInterFace()
{
public Graphical1 getObject()
{
return new Square1() ;
}
};
}
这个代码和以前的抽象工厂代码相比最大的改动就是会发现我们没有去生产出工厂的实现类,而是用了一个匿名的内部类来完成工厂的实现。