1、内部类:
把类定义在其他类的内部,称之为内部类。
内部类有哪些特点:
(1)内部类可以访问外部类的成员,包括私有。
(2)外部类要想访问内部类的成员,必须要创建内部类的对象。
按照内部类在类中定义的位置不同,可以分为如下两种格式:
(1)成员内部类(在成员位置):
1)定义在类的成员位置上。
2)内部类可以访问外部类的成员,包括私有的。
(2)局部内部类(在局部位置):
1)定义在类的方法中。
2)局部内部类可以直接方法外部类中所有成员。
3)要想使用局部内部类中的方法,需要在定义局部内部类的成员方法中,创建局部内部类的对象来调用方法。
成员内部类常见的修饰符:
(1)private : 其他类不能直接创建内部类的对象,要想使用被private修饰的内部类成员,必须在本类中间接的创建内部类对象来调用。
(2)static : 内部类如果是被static修饰的,只能访问外部类中静态成员。
创建内部类对象:
(1)格式:
外部类名.成员内部类名 对象名 = new 外部类名().new 成员内部类名();
(2)、当内部类是被静态所修饰的时候,出现了另外一种创建内部类的方式
格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
//创建外部类
class Outer{
private int num = 10;
private static int num1 = 200;
//创建内部类
//1、定义在成员的位置上(成员内部类)
class Inner{
public void show(){
System.out.println(num); //可以访问外部类的私有成员
}
}
static class Inner2 { //内部类必须是静态的才可以访问外部类中的静态成员
public static void fun() {
System.out.println(num1);
}
}
public void fun(){
int num2 = 20; //其实是被final修饰的 : final int num2 = 20;
//2、定义在局部范围内(局部内部类)
class Inner3{
int num3 = 300;
public void show1(){
//在局部内部类中引用的本地的变量必须是最终变量或者实际上的最终变量
// num2 = 22; //不可以被修改
num = 100;
num3 = 30;
System.out.println(num);
System.out.println(num2);
System.out.println(num3);
}
}
//要想使用局部内部类中的方法,需要在写有局部内部类的成员方法fun()中,创建局部内部类的对象来调用方法。
Inner3 inner3 = new Inner3();
inner3.show1();
}
//外部类要想访问内部类的show()方法,必须要创建内部类的对象
public void fun1(){
//创建内部类对象
Inner inner = new Inner();
inner.show();
}
}
//测试类
public class InnerDemo {
public static void main(String[] args) {
//第一种访问内部类方法
Outer outer = new Outer();
outer.fun1(); //通过调用fun1()方法来调用内部类的show()方法
outer.fun();
//第二种访问内部类方法 : 创建内部类对象
//格式:
//外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
Outer.Inner oi = new Outer().new Inner();
oi.show();
//当内部类是被静态所修饰的时候,出现了另外一种创建内部类的方式
//格式:
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
// Outer.Inner2 oi2 = new Outer.Inner2(); //写法1
// oi2.fun();
//因为是静态修饰的,直接通过类名调用
Outer.Inner2.fun(); //写法2
}
}
2、匿名内部类 : 局部内部类的一种。
格式:
new 类名(可以是抽象类也可以具体的类)/接口(){
要重写的方法;
};
注意: 要以分号(;)结尾
匿名内部类存在的前提 :
要存在一个类或者是一个接口,这个类可以是具体的类也可以是抽象的类。
//创建一个接口
interface Inter {
public abstract void show();
public abstract void show1();
}
class InterDemo {
public void fun() {
// 1、使用匿名内部类的形式创建对象调用show()方法
new Inter() {
@Override
public void show() {
System.out.println("昭阳");
}
@Override
public void show1() {
System.out.println("米彩");
}
}.show();
// 2、同理使用匿名内部类的形式创建对象调用show1()方法
new Inter() {
@Override
public void show() {
System.out.println("昭阳");
}
@Override
public void show1() {
System.out.println("米彩");
}
}.show1();
// 3、改进方法
//利用接口多态的形式给匿名内部类起名字,再调用show()、show1()方法
Inter inter = new Inter(){
@Override
public void show() {
System.out.println("昭阳");
}
@Override
public void show1() {
System.out.println("米彩");
}
};
inter.show();
inter.show1();
}
}
//测试类
public class InnerTest {
public static void main(String[] args) {
InterDemo id = new InterDemo();
id.fun();
}
}
3、匿名内部类练习 :
(1)、补齐程序(注意:内部类和外部类没有继承关系)
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(?);
System.out.println(??);
System.out.println(???);
}
}
}
在控制台分别输出:30,20,10
class Outer{
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(Outer.this.num); //10
}
}
}
//测试类测试一下结果
public class InnerTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
(2)按照要求,补齐代码
interface Inter {
void show();
}
class Outer {
//补齐代码
}
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
interface Inter{
public abstract void show();
}
class Outer{
//分析:
// 1、根据main方法调用的代码推出: method()是静态的,可以直接通过类名Outer访问/调用。
// 2、根据调用method()方法的参数是空,所以判定method()方法没有参数。
// 3、根据main方法中调用完method()方法之后,还能继续调用show()方法,判定method()是有返回值的,返回值是一个对象。
// 4、show()方法恰好是Inter接口中的方法,所以返回值类型是接口 Inter inter 类型。
public static Inter method(){
return new Inter() { //Inter inter = new Inter();
@Override
public void show() {
System.out.println("HelloWorld");
}
};
}
}
public class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}



