1.内部类的概述
内部类的含义可以简单的理解为:
将一个类定义在另一个类B的内部,我们将A称为内部类,将B称为外部类。
- 根据内部类定义的位置不同:可以分为成员内部类和局部内部类
成员内部类的分类 |
---|
成员内部类:内部类定义在外部类的成员位置 |
局部内部类:内部类定义在外部类的成员方法内 |
public class MyTest {
public static void main(String[] args) {
//根据内部类定义的位置不同:分为成员内部类以及局部内部类
//成员内部类:定义在外部类的成员位置
//局部内部类:定义在外部类的成员方法内
}
}
class B{
//成员内部类(位于外部类类中方法外)
class A{
}
public void show(){
//局部内部类(位于方法中)
class C{
}
}
}
1.1 成员内部类
成员内部类的访问特点 |
---|
成员内部类可以直接访问外部类的成员包括私有成员 |
外部类想要访问内部类的成员,必须创建内部类的对象 |
当内部类没有被private所修饰时,我们可以直接在外界创建成员内部类的对象 |
当内部类被private修饰时,我们可以通过在外部类的方法中创建内部类对象的方式,来进行访问内部类 |
当内部类被static所修饰时,只能访问外部类的静态成员 |
public class MyTest {
public static void main(String[] args) {
//1.内部类可以直接访问外部类的成员,其中包括外部类的私有成员
//2.外部类想要访问内部类的成员,必须创建内部类的对象
Outer outer = new Outer();
outer.waiShow();
System.out.println("=======================");
//3.我们可以在外界直接创建出成员内部类的对象
Outer.Inner inner = new Outer().new Inner();
System.out.println(inner.b);
inner.neiShow();
}
}
//外部类
class Outer{
//外部类的成员变量
int num=20;
private int a=50;
class Inner{
//内部类的成员变量
int b=30;
//内部类的成员方法
public void neiShow(){
System.out.println("内部类的show方法");
}
//内部类的测试方法
public void neiTest(){
System.out.println(num);
System.out.println(a);
}
}
public void waiShow(){
System.out.println("外部类的show方法");
Inner inner = new Inner();
System.out.println(inner.b);
inner.neiTest();
}
private void waiShow2(){
System.out.println("外部类私有的show方法");
}
}
//在定义内部类,通常会把内部类私有化
public class MyTest {
public static void main(String[] args) {
//当内部类不是私有的,可以在在外界直接创建对象
/*Wai.Nei nei = new Wai().new Nei();
nei.neiShow();
System.out.println(nei.nei);
*/
//当内部类私有化时,可以通过外部类这种间接的方式进行访问
Wai wai = new Wai();
wai.waiShow();
}
}
//外部类
class Wai{
//外部类的成员变量
int num=50;
//内部类可以进行私有化
private class Nei{
//内部类的成员变量
int nei=300;
public void neiShow(){
//内部类可以直接访问外部类的成员包含私有成员
System.out.println("内部类的show方法");
System.out.println(nei);
System.out.println(num);
}
}
public void waiShow(){
System.out.println("外部类的show方法");
Nei nei = new Nei();
System.out.println(nei.nei);
nei.neiShow();
}
}
//静态修饰符static可以修饰内部类
public class MyTest {
public static void main(String[] args) {
//当内部类没有任何修饰符修饰,
// 外界可以直接的创建内部类的对象,语法为:
/* Wai.Nei nei = new Wai().new Nei();
nei.neiShow();
*/
//静态修饰的内部类,只能访问外部类的静态成员
//静态内部类外界直接创建其对象的语法如下:
Wai.Nei nei = new Wai.Nei();
nei.neiShow();
}
}
//外部类
class Wai{
//外部类的成员变量
static int num=30;
static class Nei{
//内部类的成员变量
int a=50;
//内部类的成员方法
public void neiShow(){
System.out.println("内部类的show方法");
System.out.println(num);
System.out.println(a);
}
}
//外部类的成员方法
public void waiShow(){
System.out.println("外部类的成员方法");
}
}
1.2 局部内部类
局部内部类的访问特点 |
---|
局部内部类可以直接访问外部类的成员,包括私有成员 |
外部类想要访问内部类的成员,必须创建内部类的对象 |
局部内部类,不能在外界直接创建内部类的对象,只能通过在外部类的方法中创建内部类,在外界进行间接访问内部类 |
public class MyTest {
public static void main(String[] args) {
//1.内部类:可以直接访问外部类的成员,包括私有成员
//2.外部类想要访问内部类的成员,必须创建内部类的对象
//3.局部内部类在外界没有直接创建内部类对象的语法
Wai wai = new Wai();
wai.waiShow();
}
}
class Wai{
int num=30;
private int a=500;
public void waiShow(){
System.out.println("外部类的show方法");
//局部内部类
class Nei{
int b=20;
public void neiShow(){
System.out.println(num);
System.out.println(a);
System.out.println(b);
waiTest();
}
}
Nei nei = new Nei();
nei.neiShow();
}
private void waiTest(){
System.out.println("外部类的私有方法");
}
}
- 局部内部类,访问外部类的局部变量,这个局部变量必须为一常量。JDK以后,final会默认存在
public class MyTest {
public static void main(String[] args) {
Outer outer = new Outer();
outer.waiShow(100,200);
}
}
class Outer{
public int num=20;
public void waiShow(final int a,final int b){
//外部类的成员变量
final int ee=50;
class Inner{
public void neiShow(){
/*局部内部类,访问外部类的局部变量,
这个局部变量必须为一常量
Jdk1.8之后fianl会默认添上
*/
System.out.println(num);
System.out.println(a);
System.out.println(b);
System.out.println(ee);
}
}
Inner inner = new Inner();
inner.neiShow();
}
}
2. 匿名内部类
-
匿名内部类:就是局部内部类的一种简写的形式。
-
匿名内部类,本质是一个对象,是实现该接口或者继承该抽象类的子类对象。
-
获得子类对象的方法有两种:1.直接创建子类对象 2.可以使用匿名内部类
public class MyTest {
public static void main(String[] args) {
//匿名内部类:是局部内部类的一种简写的形式
//匿名内部类,本质上是一个对象,
//是实现该接口或者是继承该抽象类的子类对象
//获得子类对象的方式一:直接创建子类对象
/*B b = new B();
b.show();
*/
//获得子类对象的方式二:通过匿名内部类进行实现
//利用多态的形式对匿名内部类进行接收
A a =new A(){
@Override
public void show() {
System.out.println("我重写抽象类的方法1");
}
};
a.show();
}
}
abstract class A{
public abstract void show();
}
/*class B extends A{
@Override
public void show() {
System.out.println("我重写抽象类的方法");
}
}
*/
2.1 匿名内部类作为抽象类的子类对象
- 匿名内部类,本质上是一个对象,可以是作为抽象类的子类对象
//匿名内部类作为抽象类的子类对象
public class MyTest2 {
public static void main(String[] args) {
/*BB bb = new BB();
bb.aa();
bb.myaa();
*/
AA aa= new AA(){
@Override
public void aa() {
System.out.println("我重写了抽象类的aa方法1");
}
@Override
public void myaa() {
System.out.println("我重写了抽象类的myaa方法1");
}
};
aa.aa();
aa.myaa();
test(new AA(){
@Override
public void aa() {
System.out.println("我重写了抽象类中的aa方法22");
}
@Override
public void myaa() {
System.out.println("我重写了抽象类中的myaa方法22");
}
});
}
public static void test(AA aa){
aa.myaa();
}
}
abstract class AA{
public abstract void aa();
public abstract void myaa();
}
/*class BB extends AA{
@Override
public void aa() {
System.out.println("我重写了抽象类中的aa方法");
}
@Override
public void myaa() {
System.out.println("我重写了抽象类中的myaa方法");
}
}
*/
2.2 匿名内部类作为接口的子类对象
- 匿名内部类,本质上是一个对象,可以是作为接口的子类对象
//匿名内部类作为接口的子类对象
public class MyTest {
public static void main(String[] args) {
/*C c = new C();
c.show();
*/
MyInterface myInterface=new MyInterface(){
@Override
public void show() {
System.out.println("我重写了接口中的方法1");
}
};
myInterface.show();
test(new MyInterface() {
@Override
public void show() {
System.out.println("我重写了接口中的方法2");
}
});
}
public static void test(MyInterface myInterface){
myInterface.show();
}
}
interface MyInterface{
void show();
}
/*class C implements MyInterface{
@Override
public void show() {
System.out.println("我重写了接口中的方法");
}
}
*/
2.3 匿名内部类作为具体类的子类对象
- 当然,匿名内部类也可以作为具体类的子类对象
//匿名内部类可以作为具体类的子类对象
public class MyTest {
public static void main(String[] args) {
/*Zi zi = new Zi();
zi.show();
*/
Fu fu= new Fu(){
@Override
public void show() {
System.out.println("zi show");
}
};
fu.show();
}
}
class Fu{
public void show(){
System.out.println("父类的show方法");
}
}
/*class Zi extends Fu{
@Override
public void show() {
System.out.println("子类重写的show方法");
}
}
*/
3.内部接口
- 内部类:在一个类中可以定义一个类
- 内部接口:一个类中定义一个接口
- 注意:内部接口可以私有化,当内部接口私有化时,可以在外部类中的创建接口的匿名内部类
//内部接口私有化时,在外部类中创建接口的匿名内部类
public class MyTest {
public static void main(String[] args) {
/* new Outer.A(){
@Override
public void show() {
System.out.println("hahaha");
}
}.show();
*/
Outer outer = new Outer();
outer.outerShow();
}
}
//外部类
class Outer{
//内部接口
private interface A{
void show();
}
public void outerShow(){
new A(){
@Override
public void show() {
System.out.println("hihihi");
}
}.show();
}
}