- 什么是内部类?
内部类:将一个类定义到另一个类的内部,就称之为内部类,根据内部类定义的位置不同,可以分为成员内部类,和局部内部类
class B{
//成员内部类
class A {
}
public void show(){
//局部内部类
class C{
}
}
}
- 内部类的访问特点
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员必须创建对象 - 内部类的作用
内部类提供了某种进入其外围类的窗口
每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经
继承了某个(接口)的实现,对应内部类都没有影响。
内部类使得多重继承的解决方案更加完整。虽然接口解决可部分问题,
但是内部类有效的实现了多重继承。也就是说:内部类允许继承多个非接口
类型(类或者抽象类)。 我认为这是内部类最重要的一个作用。 - Java内部类有什么好处?为什么需要内部类?
首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。不过你可能要质疑,更改一下方法的不就行了吗?的确,以此作为设计内部类的理由,实在没有说服力。真正的原因是这样的,java中的内部类和接口加在一起,可以的解决常被C++程序员抱怨java中存在的一个问题 没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。
----------转自https://blog.csdn.net/gaoyong_stone/article/details/79556287-
静态内部类
- 和普通的类一样,内部类也有静态的与非静态之分,静态内 部类只能访问外部类的静态成员。
- 访问静态内部类的方式:
public class MyTest {
public static void main(String[] args) {
//Wai.Nei nei = new Wai().new Nei();
//nei.neiShow();
//内部类用static修饰后,创建对象的方式,是如下方式
Wai.Nei nei=new Wai.Nei();
nei.neiShow();
//静态内部类,只能访问外部类的静态成员
}
}
class Wai{
static int num=100;
static class Nei{
int n=10;
public void neiShow(){
System.out.println("这是内部类的show方法");
System.out.println(num);
test();
}
}
public static void test(){
System.out.println("外部类的test方法");
}
}
局部内部类
- 局部内部类要访问外部类的局部变量,这个局部变量,前面要加上final让他变为一个常量,jdk1.8已经默认加上了。
- 局部内部类访问局部变量为什么必须用final修饰
因为局部会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。
为了让数据还能继续被使用,就用final修饰,这样,在堆内存里面存储的其实是一个常量值。
代码演示:
- 局部内部类外界无法直接创建对象,注意外界访问局部内部类的方法。
public class MyTest {
public static void main(String[] args) {
Wai wai = new Wai();
wai.waiShow(4);
}
class Wai {
int num = 100;
public void waiShow(final int a) {
//定义一个局部变量
final int b = 10;
class Nei {
final int n = 1;
public void neiShow() {
System.out.println(n);
System.out.println(num);
System.out.println(b);
System.out.println(a);
}
}
Nei nei = new Nei();
nei.neiShow();
}
}
匿名内部类
- 匿名内部类实质上就是局部内部类的简写形式
- 匿名内部类本质上是一个对象,是实现了该接口或是继承了该抽象类的子类对象
- 当只需要实现接口或是继承抽象类的子类来传参时使用匿名内部类可以大大的提高代码的简洁度
- 它的语法规则是这样的
new interfacename(){…}; 或 new superclassname(){…};
下面是具体的实现例子: - 实现接口的例子,注解的是不使用匿名内部类的做法
public class MyTest {
public static void main(String[] args) {
//MyInterface myInterface= new MyClass();
//myInterface.show();
//匿名内部类
new MyInterface() {
@Override
public void show() {
System.out.println("我重写了接口中的抽象方法");
}
}.show();
System.out.println("-----------------");
new MyInterface(){
@Override
public void show() {
System.out.println("又是一个匿名内部类,重写了接口中的show方法");
}
}.show();
}
}
interface MyInterface {
void show();
}
//class MyClass implements MyInterface{
// @Override
// public void show() {
// System.out.println("重写了接口中的抽象方法");
// }
//}
- 继承抽象类的子类对象
public class MyTest2 {
public static void main(String[] args) {
//AA aa = new BB();
//aa.aa();
//aa.bb();
//匿名内部类,是AA抽象了的一个子类对象
new AA() {
@Override
void aa() {
System.out.println("我重写了抽象类中的aa方法");
}
@Override
void bb() {
System.out.println("我重写了抽象类中的bb方法");
}
};
System.out.println("--------------");
new AA() {
@Override
void aa() {
System.out.println("我重写了抽象类中的aa222方法");
}
@Override
void bb() {
System.out.println("我重写了抽象类中的bb222方法");
}
}.aa();
System.out.println("---------------------------");
new AA() {
@Override
void aa() {
System.out.println("我重写了抽象类中的aa3333方法");
}
@Override
void bb() {
System.out.println("我重写了抽象类中的bb3333方法");
}
}.bb();
System.out.println("------------------------------------");
//多态,父类引用,指向子类对象
AA a= new AA() {
@Override
void aa() {
System.out.println("我重写了抽象类中的aa444方法");
}
@Override
void bb() {
System.out.println("我重写了抽象类中的bb44444方法");
}
};
a.aa();
a.bb();
}
}
abstract class AA{
abstract void aa();
abstract void bb();
}
//class BB extends AA{
//
// @Override
// void aa() {
// System.out.println("我重写了抽象类中的aa方法");
// }
//
// @Override
// void bb() {
// System.out.println("我重写了抽象类中的bb方法");
// }
//}
`