纸上得来终觉浅
之前总结了Java的一些类的初始化和其他特性,留些内部类还没有总结,还是不能漏的,下面就总结和实践下Java的内部类:
1.内部类的分类
1)静态内部类:由Static修饰(之前在讲类的初始化的时候提到过,一般类名是不可以由Static修饰的,但是有特例,这个就是)
2)非静态内部类:
成员内部类 (在总结包的访问权限时,提到过一般类名只能是默认或者public修饰,成员内部类是可以可以由任何修饰符修饰的;上面的静态内部类也可以由任何修饰符修饰)
局部内部类 (修饰符只能是默认的)
匿名内部类 (修饰符只能是默认的)
2.实例
1)静态内部类
内部类中只能访问外部类的静态属性;
package roadArchitectWeb.Test;
import com.sun.org.apache.bcel.internal.generic.StackInstruction;
import roadArchitectWeb.Test.Out.In;
/*外部类*/
class Out{
private String allName;
private static String te = "out";
/*内部类*/
static class In{
/*内部类中的方法可以访问外部类中的任意属性(不管是什么修饰符)*/
public static void getOutPropertity(){
/*不能访问外部类中的非静态成员变量*/
// System.out.println("Out.In.getOutPropertity():"+Out.allName);
/*能够偶访问外部类中的静态成员变量*/
System.out.println("Out.In.getOutPropertity():"+Out.te);
}
}
}
public class Test16{
public static void main(String[] args) {
Out.In.getOutPropertity();
}
}
结果如下:
Out.In.getOutPropertity():out
2)成员内部类
内部类可以访问外部类的所有成员,包括成员变量和成员方法;
外部类要访问内部类成员,就要创建一个内部类的对象,然后通过对象的引用来访问;
package roadArchitectWeb.Test;
/*外部类*/
class Out{
private String outName;
private String allName;
public String getAllName() {
return allName;
}
public void setAllName(String allName) {
this.allName = allName;
}
public String getOutName() {
return outName;
}
public void setOutName(String outName) {
this.outName = outName;
}
/*外部类中的方法可以通过new的方式新建内部实例,然后访问其中的属性*/
public void getInPropertity(){
In in = new In();
in.setInName("This is In inName from out");
in.setAllName("This is In allName from out");
System.out.println("Out.getInPropertity():"+in.getInName());
}
/*内部类*/
class In{
public String inName;
private String allName;
public String getAllName() {
return allName;
}
public void setAllName(String allName) {
this.allName = allName;
}
public String getInName() {
return inName;
}
public void setInName(String inName) {
this.inName = inName;
}
/*内部类中的方法可以访问外部类中的任意属性(不管是什么修饰符)*/
public void getOutPropertity(){
System.out.println("Out.In.getOutPropertity():"+outName);
System.out.println("Out.In.getOutPropertity():in中的allName:"+allName);
System.out.println("Out.In.getOutPropertity():out中的allName:"+Out.this.allName);
}
}
}
public class Test16{
public static void main(String[] args) {
Out out = new Out();
out.setOutName("This is Out outName");
out.setAllName("This is Out allName");
/*实例化方式*/
Out.In in = out.new In();
in.setInName("This is In inName from main");
in.setAllName("This is In allName from main");
out.getInPropertity();
in.getOutPropertity();
}
}
结果如下:
Out.getInPropertity():This is In inName from out
Out.In.getOutPropertity():This is Out outName
Out.In.getOutPropertity():in中的allName:This is In allName from main
Out.In.getOutPropertity():out中的allName:This is Out allName
注:
A:内部类中的成员和外部类中的成员命名相同时,在内部类中默认访问自己的成员,要想访问外部的,要通过:”外部类.this.成员变量“ 的形式。
B:为什么内部类可以由任意修饰符修饰呢,可以这样理解,它位于外部类内部,相当于其中的一个成员。
3)局部内部类定义在方法中的类;
package roadArchitectWeb.Test;
class Animal{
public void play(){
System.out.println("Animal.play()");
}
}
class People{
public Animal findAnimal(){
class Dog extends Animal{
String name = "Hast";
public void play(){
System.out.println("People.findAnimal().Dog.play():"+name);
}
}
return new Dog();
}
}
public class Test17 {
public static void main(String[] args) {
People people = new People();
Animal animal = people.findAnimal();
animal.play();
}
}
结果如下:
People.findAnimal().Dog.play():Hast
4)匿名内部类
省略了一个类的书写
package roadArchitectWeb.Test;
class Animals{
public void eat(){
System.out.println("Animal.eat()");
}
}
public class Test18 {
public static void main(String[] args) {
Animals animals = new Animals(){
public void eat() {
System.out.println("Test18.main(...).new Animals() {...}.eat()");
};
};
animals.eat();
}
}
结果如下:
Test18.main(...).new Animals() {...}.eat()
3.为什么要使用内部类?
其实就是内部类的作用:
1)实现多继承可以使用接口,类只能单继承,可以使用内部类间接实现多继承,这样可以少写接口和类,为什么这么说?实例如下:
</pre><pre name="code" class="java">package roadArchitectWeb.Test;
class Exam1{
public void Exam1(){
System.out.println("Exam1.Exam1()");
}
}
class Exam2{
public void Exam2(){
System.out.println("Exam2.Exam2()");
}
}
class allEamp{
class Test1 extends Exam1{
public void Exam1(){
super.Exam1();
System.out.println("allEamp.Test1.Exam1()");
}
}
class Test2 extends Exam2{
public void Exam2(){
super.Exam2();
System.out.println("allEamp.Test2.Exam2()");
}
}
public void syt1(){
new Test1().Exam1();
}
public void syt2(){
new Test2().Exam2();
}
}
public class Test19 {
public static void main(String[] args) {
allEamp allEamp = new allEamp();
allEamp.syt1();
allEamp.syt2();
}
}
</pre>结果如下:</p><p><pre name="code" class="html"><pre name="code" class="html">Exam1.Exam1()
allEamp.Test1.Exam1()
Exam2.Exam2()
allEamp.Test2.Exam2()
上面的例子当然可以使用在原有的两个类的基础上加两个接口,或者加上两个实现类,再组合到allEamp中;
2)可以将有一定关系的类组合在一起,又能够实现隐藏。
在看TIJ的内部类这一章,其他作用后面总结。