02
2018
12

JAVA学习-Java高级特性之内部类

Java高级特性之内部类

所谓内部类(Inner Class),就是将一个类定义在另一个类的内部。内部的类称之为内部类。

内部类的主要特点

内部类可以很好的实现隐藏,可以使用protected、private修饰符。

内部类可以直接访问外部类的所有成员,包括私有的成员。

外部类不能直接访问内部类的成员,必须首先要建立内部类的对象才可访问。

内部类可以解决一些问题,比如间接地去实现多继承。可以避免修改接口而实现同一个类中两种同名方法的调用。

成员内部类

成员内部类特点

成员内部类属于外部类的实例成员,成员内部类可以有public/private/default/protected权限修饰符。在成员内部类中访问外部的成员方法和属性,要使用“外部类名.this.成员方法”和“外部类名.this.成员属性”的形式

创建成员内部类的实例使用“外部类名.内部类名 实例名 = 外部类实例名.new 内部类名()”的形式

成员内部类有以下限制

成员内部类不能与外部类重名

不能在成员内部类定义static属性、方法和类(static final形式的常量定义除外)。因为一个成员内部类实例必然与一个外部类实例关联,static成员完全可以移到外部类中去

demo:

public class MemberInnerClassDemo
{
public static void main(String[]args)
{
//创建外部类对象
Outer1 outer1=new Outer1();
//创建内部类对象
Outer1.Inner1 inner1=outer1.new Inner1();
inner1.innerShow();
}
}
class Outer1{
private String name="张三";
private int num1=10;
public void outerShow(){
System.out.println("姓名:"+name+",编号:"+num1);
}
//内部类,当内部类声明为private时,只能在对应的外部类中使用,不能在其他类中使用
public class Inner1{
private String name="李四";
private int num1=12;
//private static int num2=30;//报错:内部类Outer1.Inner1中的静态声明非法
private static final int num3=50;//常量可以
public void innerShow(){
System.out.println("内部类 姓名:"+name+",编号:"+num1);
//同名时,用Outer1.this区分
System.out.println("外部类姓名:"+Outer1.this.name);
outerShow();//直接访问外部类的属性和方法
}
}
}

效果:


使用内部类间接实现多继承

由于一个类只能直接继承自一个父类,通过多个内部类分别继承自一个类,就可以间接实现多继承


demo:

public class MultiExtendsDemo
{
public static void main(String[]args)
{
//创建外部类对象
C c=new C();
c.showA();
c.showB();
}
}
class A{
public void showA(){
System.out.println("A");
}
}
class B{
public void showB(){
System.out.println("B");
}
}
class C{
private class A1 extends A{
public void showA(){
super.showA();
}
}
private class B1 extends B{
public void showB(){
super.showB();
}
}
public void showA(){
new A1().showA();
}
public void showB(){
new B1().showB();
}
}

效果:


使用内部类间接实现父类与接口同名方法的重写与实现

使用内部类去实现接口方法,从而使得接口方法与父类抽象方法不冲突。

但这种方法没太大意义,当父类与接口方法重名时,理应改其中一个的方法名。这里只是说了一种思维方式能够处理重名问题。


demo:

public class SameFunctionDemo
{
public static void main(String[]args)
{
//创建外部类对象
Son son=new Son();
son.show();
son.show2();
}
}
abstract class Parent{
public abstract void show();
}
interface IShow{
void show();
}
class Son extends Parent{
public void show(){
System.out.println("抽象类中的show()");
}
private class Inner2 implements IShow{
public void show(){
System.out.println("接口中的show()");
}
}
public void show2(){
new Inner2().show();
}
}

效果:


Java高级特性之内部类

静态内部类及应用

静态内部类特点

使用static修饰的成员内部类叫静态内部类。

静态内部类跟外部类没有任何关系,只是在生成类定义时有影响。静态内部类可以看做是与外部类平级的类。使用方式与外部类平级的类完全相同

创建静态内部类的实例使用“外部类名.内部类名 实例名 = new 外部类名.内部类名()”

静态内部类有以下限制

静态内部类不能与外部类重名

静态内部类不能访问外部类的非静态和属性和方法、外部类不能访问内部类的非静态的属性和方法。

demo:

public class StaticInnerClassDemo
{
public static void main(String[]args)
{
//创建静态内部类对象
Outer2.Inner2 inner2=new Outer2.Inner2();
inner2.innerShow();
Outer2 outer2=new Outer2();
outer2.outerShow();
}
}
class Outer2{
private String name="张三";
private int num1=10;
private static int num2=5;
public void outerShow(){
System.out.println("姓名:"+name+",编号:"+num1);
System.out.println(Inner2.num3);//外部类访问内部类的静态成员
}
//static内部类与外部类平级,跟外部类没有任何关系
public static class Inner2{
private String name="李四";
private int num1=12;
private static int num3=50;//常量
public void innerShow(){
System.out.println("内部类 姓名:"+name+",编号:"+num1);
//System.out.println(Outer2.this.num1);//错误: 无法从静态上下文中引用非静态 变量 this
System.out.println(Outer2.num2);//内部类访问外部类的静态成员
}
}
}

效果:



Java高级特性之内部类

匿名内部类及应用

匿名内部类特点

匿名内部类是没有名称的内部类,没办法引用它们。必须在创建时作为new语句的一部分来声明并创建它们的实例。

匿名内部类必须继承一个类(抽象的、非抽象的都行)或者实现一个接口。如果父类(或者接口)是抽象类,则匿名内部类必须实现其所有抽象方法

匿名内部类中可以定义代码块,用于实例的初始化,但不能定义静态代码块。

匿名内部类语法

new interface/superclass(){//类体} 这种形式的new语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口,并同时创建该匿名类的一个新实例


demo:

public class AnonymousInnerClassDemo
{
public static void main(String[]args)
{
Person p=new Person();
//传统写法
//Animal dog=new Dog();
//p.feed(dog);
//创建匿名内部类对象
IAnimal dog = new IAnimal(){//匿名对象,实现接口
public void eat(){//匿名内部类实现抽象方法
System.out.println("dog 啃骨头");
}
};
p.feed(dog);
Animal cat = new Animal(){//匿名对象,继承抽象类
private String name="lili";
public void eat(){//匿名内部类实现抽象方法
System.out.println("cat 吃鱼");
}
public void show(){//匿名内部类可以实现自己的方法,但是引用变量为父类或接口,不能实际调用
System.out.println("我是 cat "+name);
}
};
p.feed(cat);
//cat.show();//父类引用变量不能调用子类特有的成员
}
}
class Person{
public void feed(Animal animal){
System.out.print("人喂动物  ");
animal.eat();
}
public void feed(IAnimal animal){
System.out.print("人喂动物  ");
animal.eat();
}
}
abstract class Animal{
public abstract void eat();
}
interface IAnimal{
public abstract void eat();
}
/*class Dog extends Animal{
public void eat(){
System.out.println("dog 啃骨头");
}
}
*/

效果:



Java高级特性之内部类

局部内部类及应用(很少使用)

局部内部类特点

定义在代码块、方法体内的类叫局部内部类。

局部内部类访问外部类的属性和方法使用“外部类名.this.属性名”和“外部类名.this.方法名()”的形式。

对外部世界完全隐藏,只能在其作用域内生成对象。

局部内部类有以下限制

局部内部类不能加访问修饰符,因为它们不是类成员。

局部内部类不能与外部类重名。

局部内部类访问作用域内的局部变量,该局部变量需要使用final修饰。


demo:

public class LocalInnerClassDemo
{
public static void main(String[]args)
{
Outer3 outer=new Outer3();
outer.showOuter();
}
}
class Outer3{
private String name="张三";
private int num1=10;
private static int num2=20;
public void showOuter(){
int num4 = 50;
final int num5 = 80;
//局部内部类不能加访问修饰符
class Inner3{
private int num3=30;
private int num1=100;
public void showInner(){
System.out.println(num3);
System.out.println("外部类成员变量name:"+Outer3.this.name);
System.out.println("外部类成员变量num1:"+Outer3.this.num1);
System.out.println("外部类静态变量num2:"+Outer3.num2);
//报错:num4需要被声明为最终类型
//System.out.println("作用域内的局部变量num4:"+num4);
System.out.println("作用域内的局部常量num5:"+num5);
}
}
Inner3 inner=new Inner3();
inner.showInner();
}
}

效果:



版权声明:
作者:真爱无限 出处:http://www.pukuimin.top 本文为博主原创文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.
« 上一篇下一篇 »

相关文章:

评论列表:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。