1. 内部类的定义与使用
1.1 内部类的基本概念
内部类:所谓内部类就是在一个类的内部进行其他类结构的嵌套操作
观察内部类的简单定义
package Inner;
/**
* Author:weiwei
* description:简单内部类
* Creat:2019/3/29
**/
class Outer{
private String msg = "Hello World!";
class Inner{
public void print(){//定义一个内部类
System.out.println(msg);//调用msg属性
}
}
//在外部类中定义一个方法该方法负责产生内部类对象并且调用print()方法
public void fun(){
Inner in = new Inner();//内部类对象
in.print();
}
}
public class TestInner1 {
public static void main(String[] args) {
Outer outer = new Outer();//外部类对象
outer.fun();//外部类方法
}
}
通过上述代码发现,虽然内部类破坏了程序的结构,但是从另一方面来讲,内部类可以方便操作外部类的私有访问
修改上述代码,把内部类拆开到外部,主方法代码不变,实现相同的功能
package Inner;
/**
* Author:weiwei
* description:
* Creat:2019/3/29
**/
class Outer{
private String msg = "Hello World!";
public String getMsg(){//通过此方法才能获得属性
return this.msg;
}
public void fun(){//现在由out对象调用了fun()方法
Inner inner = new Inner(this);//this表示当前对象
inner.print();
}
}
class Inner{
private Outer outer;
public Inner(Outer outer){//Inner.outer=main.outer
this.outer = outer;//引用传递
}
public void print(){
System.out.println(outer.getMsg());
}
}
public class TestInner2 {
public static void main(String[] args) {
Outer outer = new Outer();//实例化Outer对象
outer.fun();//调用outer类方法
}
}
1.2 内部类为什么存在
- 内部类方法可以访问该类定义所在作用域中的数据,包括被 private 修饰的私有数据
- 内部类可以对同一包中的其他类隐藏起来
- 内部类可以实现 java 单继承的缺陷
- 当我们想要定义一个回调函数却不想写大量代码的时候我们可以选择使用匿名内部类来实现
使用内部类来实现多继承
package Inner;
/**
* Author:weiwei
* description:内部类实现多继承
* Creat:2019/3/29
**/
class A{
private String name = "A类的私有域";
public String getName(){
return name;
}
}
class B{
private int age = 20;
public int getAge(){
return age;
}
}
class Outter{
private class InnerClassA extends A{
public String name(){
return super.getName();
}
}
private class InnerClassB extends B{
public int age(){
return super.getAge();
}
}
public String name(){
return new InnerClassA().name();
}
public int age(){
return new InnerClassB().age();
}
}
public class TestInner3 {
public static void main(String[] args) {
Outter outter = new Outter();
System.out.println(outter.name());
System.out.println(outter.age());
}
}
1.3 内部类与外部类的关系
- 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的
- 内部类是一个相对独立的实体,与外部类不是is-a关系
- 内部类可以直接访问外部类的元素(包含私有域),但是外部类不可以直接访问内部类的元素
- 外部类可以通过内部类引用间接访问内部类元素
内部类可以直接访问外部类元素
package Inner;
/**
* Author:weiwei
* description:内部类可以直接访问外部类的元素
* Creat:2019/3/29
**/
class Outter{
private String outName;
private int outAge;
class Inner{
private int InnerAge;
public Inner(){
Outter.this.outName = "I am Outter class";
Outter.this.outAge = 20;//内部类直接访问外部类属性
}
public void display(){
System.out.println(outName);
System.out.println(outAge);
}
}
}
public class TestInner4 {
public static void main(String[] args) {
Outter.Inner inner = new Outter().new Inner();
inner.display();
}
}
外部类可以通过内部类引用间接访问内部类元素
package Inner;
/**
* Author:weiwei
* description:外部类可以通过内部类引用间接访问内部类元素
* Creat:2019/3/29
**/
class Outter{
private void display(){
//外部类访问内部元素,需要通过内部类引用来访问
Inner inner = new Inner();
inner.display();
}
class Inner{
public void display(){
System.out.println("I am InnerClass ");
}
}
}
public class TestInner5 {
public static void main(String[] args) {
Outter outter = new Outter();
outter.display();
}
}
2. 内部类
2.1 内部类分类
在Java中内部类分为:
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
2.2 在外部类外部创建内部类
外部类.内部类 内部类对象 = new 外部类().new 内部类();
Outter.Inner inner = new Outter.new Inner();
2.3 在外部类内部创建内部类
内部类 内部类对象 = new 内部类();
Inner inner = new Inner();
3. 内部类详解
3.1 成员内部类
在成员内部类中要注意两点:
1. 成员内部类中不能存在任何static的变量和方法
2. 成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类
3.2 静态内部类
静态内部类:用关键字static修饰的内部类
注意:
- 静态内部类的创建是不需要依赖于外围类,可以直接创建
- 静态内部类不可以使用任何外围类的非static成员变量和方法,而内部类则都可以
外部类创建语法:
外部类.内部类 内部类对象 = new 外部类.内部类();
使用static创建静态内部类
package Inner;
/**
* Author:weiwei
* description:静态内部类
* Creat:2019/3/29
**/
class Outter{
private static String msg = "Hell World!";
static class Inner{//定义一个静态内部类
public void print(){//此时只能使用外部类中的static操作
System.out.println(msg);
}
}
public void fun(){
Inner inner = new Inner();
inner.print();
}
}
public class TestInner6 {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
inner.print();
}
}
3.3 方法内部类
方法内部类:方法内部类定义在外部类的方法中,方法内部类只能在该方法中被使用,方法内部类又被称为局部内部类
注意:
- 局部内类不允许使用访问权限修饰符 public private protected 均不允许
- 局部内部类对外完全隐藏,除了创建这个类的方法可以访问它其他的地方是不允许访问的。
- 局部内部类要想使用方法形参,该形参必须用final声明(JDK8形参变为隐式final声明).
使用方法内部类
package Inner;
/**
* Author:weiwei
* description:方法内部类
* Creat:2019/3/29
**/
class Outter {
private int num;
public void display(int test){
class Inner{
private void fun(){
num++;
System.out.println(num);
System.out.println(test);
}
}
new Inner().fun();
}
}
public class TestInner7 {
public static void main(String[] args) {
Outter outter = new Outter();
outter.display(20);
}
}
3.4 匿名内部类
匿名内部类:就是一个没有名字的方法内部类
注意:
- 匿名内部类是没有访问修饰符的。
- 匿名内部类必须继承一个抽象类或者实现一个接口
- 匿名内部类中不能存在任何静态成员或方法
- 匿名内部类是没有构造方法的,因为它没有类名。
- 与局部内部相同匿名内部类也可以引用方法形参。此形参也必须声明为 final
使用内部类
package Inner;
/**
* Author:weiwei
* description:匿名内部类
* Creat:2019/3/29
**/
interface MyInterface{
void test();
}
class Outter{
private int num;
void display(int para){
//匿名内部类实现了MyInterface接口
new MyInterface(){
@Override
public void test(){
System.out.println("匿名内部类"+para);
}
}.test();
}
}
public class TestInner8 {
public static void main(String[] args) {
Outter outter = new Outter();
outter.display(20);
}
}
总结:
内部类的使用暂时不作为设计的首选,内部类的特点如下
1.破坏了程序的结构
2.方便进行私有属性的访问。(外部类也可以访问内部类的私有域)
3.如果发现类名称上出现了 . ,应当立即想到内部类的概念。