上次说到类之中还可以嵌套类,嵌套其中的类就是内部类。内部类大致可分为四类,分别是:成员内部类,局部内部类,匿名内部类和静态内部类。
文章目录
成员内部类
定义语法
成员内部类是最普通和简单的内部类,即把类定义在一个类之中,如同成员变量一般。
public class 外部类{
public class 内部类{
}
}
代码示例:
public class human {
public human(){}
public class brain{
public public brain(){}
public void think(){
System.out.println("正在思考");
}
}
}
brain类就是human类的一个成员内部类。
成员内部类的访问权限也很广,可以用public、protected、默认、private来修饰。这是由于成员内部类就如同一个类的成员变量一样,不像外部类只能由public和默认权限修饰词来修饰。
使用方法
1、内部类中,可以随意使用外部类成员。
2、外部类中,使用内部类成员时需要创建内部类对象。
3、在无关类中调用内部类成员:
a.间接调用,在外部类中的成员方法中创建内部类对象
b.直接调用,需要创建内部类对象:
外部类.内部类 类名= new 外部类().new 内部类();
4、在内部类和外部类有同名成员变量时,会出现隐藏现象,会默认访问内部类成员,此时需要区分时便用到如下格式:
外部类成员变量: 外部类名.this.变量名
内部类成员变量: this.变量名
局部变量: 变量名
成员内部类是依附在外部类存在的,如果需要创建一个内部类对象,必须要先存在一个外部类对象,如上述第3点所说。
代码示例:
public class Javasample {
public static void main(String[] args) {
outter out=new outter();
outter.inner inner1=out.new inner();
//方法1,直接创建内部类对象
outter.inner inner2=out.createinner();
//方法2,调用方法创建内部类对象
}
}
class outter{
public inner inner= null;
public inner createinner(){
//使用方法创建内部类对象
if(inner==null) {
inner inner = new inner();
}
return inner;
}
class inner{
public inner() {
System.out.println("创造了内部类");
}
}
}
结果如下:
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。(局部内部类和成员内部类的区别与局部变量和成员变量的区别类似)
注意!: 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的,直接什么都不写(默认)。
代码示例:
public class Javasample {
public static void main(String[] args) {
man m=new man();
//创建一个man类对象
person w=m.createwoman();
/*调用createwoman()方法
同时woman类继承了person类
所以可以返回一个woman类给声明为person的 w
*/
}
}
class person{
public person(){
}
}
class man extends person{
public man(){
System.out.println("创建了男人");
}
public person createwoman(){
//创建woman类
class woman extends person{
public woman(){
System.out.println("创建了女人");
}
}
return new woman();
}
}
结果如下:
匿名内部类
匿名内部类应该包括在局部内部类之中,二者非常相似,不同的是匿名内部类没有类名,并且匿名内部类只能使用一次。如果一个局部内部类只需要用到一次,就可以使用匿名内部类。
定义
public class Javasample {
interface sayHello{
public void sayHi();
}
public void greetsomeone(){
abstract class greeting{
public abstract void greet();
}
//匿名内部类实现接口
sayHello chinesegreet=new sayHello() {
/*这里没有实例化接口
接口可以看作特殊的抽象类,不能实例化
这里是用一个匿名类实现了
*/
@Override
public void sayHi() {
System.out.println("你好");
}
};//注意!
//匿名内部类继承抽象类 实现抽象类中的抽象方法
greeting english=new greeting() {
/*这里没有实例化greeting类
抽象类不能实例化
这里是用一个匿名类继承了抽象类
*/
@Override
public void greet() {
System.out.println("hello");
}
};//注意!
chinesegreet.sayHi();
english.greet();
}
public static void main(String[] args) {
Javasample j=new Javasample();
j.greetsomeone();
}
}
结果如下:
注意!:匿名类是一个表达式,因此在定义的最后用分号 “;” 结束。
匿名类定义完可以直接使用。
语法
匿名内部类实现接口
将上面的匿名内部类实现接口单独拎出来:
public class Javasample {
interface sayHello{
public void sayHi();
}
public void greetsomeone(){
sayHello chinesegreet=new sayHello() {
@Override
public void sayHi() {
System.out.println("你好");
}
};
//匿名内部类继承抽象类 实现抽象类中的抽象方法
chinesegreet.sayHi();
}
public static void main(String[] args) {
Javasample j=new Javasample();
j.greetsomeone();
}
}
接口名 对象名 = new 接口名(){
重写方法;
};
不要忘记分号。
匿名内部类继承父类
上面的代码是继承抽象类,现在改成继承普通类,格式差不多。
代码示例:
public class Javasample {
private final String answer = "I'm just doing good.";
class greeting {
public void greet() {
System.out.println("Hi");
}
public void ans() {}
}
greeting englishgreet = new greeting() {
@Override
public void greet() {
System.out.println("Hello");//继承并重写父类方法
}
public void ans(){
System.out.println(answer);//访问外部类的final变量
this.run();//只能在匿名内部类中调用自己的方法
}
public void run(){
//匿名内部类自己特有的方法
System.out.println("run fast");
}
};
public void Hello() {
englishgreet.greet();
englishgreet.ans();
}
public static void main(String[] args) {
Javasample j = new Javasample();
j.Hello();
}
}
结果如下:
注意!:匿名内部类中的非继承的、自己独有的方法无法在匿名内部类外被调用。(如run()方法)
静态内部类
静态内部类也是定义在另一个类里面的类,并且由关键字static来修饰。静态内部类不需要依附于外部类,并且可以在没有外部类的对象的情况下创建静态内部类的对象。这些特性和静态变量很像,而且静态内部类无法调用外部类中非static的成员变量和方法。
代码示例:
public class Javasample {
public static void main(String[] args) {
outter.inner in =new outter.inner();
}
}
class outter{
int a=10;
static int b=20;
static class inner{
public inner(){
System.out.println(a);
}
}
}
结果如下:
public class Javasample {
public static void main(String[] args) {
outter.inner in =new outter.inner();
}
}
class outter{
int a=10;
static int b=20;
static class inner{
public inner(){
System.out.println(b);
}
}
}
结果如下: