内部类
- 概念:把类定义在其他类的内部,这个类被称为内部类
- 内部类访问特定
(1)内部类可以直接访问外部类的所有成员
(2)外部类要访问内部类的成员,必须创建对象
class A{
private int Anum = 20;
public void methodA(){
System.out.println("我是外部类方法");
}
public void testA(){
//外部类A调用内部类B的成员必须先创建内部类B对象
B b = new B();
System.out.println(b.Bnum);//调用内部类B成员变量
b.methodB();//调用内部类B成员方法
}
class B{
int Bnum = 30;
public void methodB(){
System.out.println("我是内部类方法");
}
public void testB(){
//内部类B可以直接调用外部类A的成员变量
System.out.println(Anum);//调用外部类A的成员变量
methodA();//调用外部类A的成员方法
}
}
}
- 内部类分为成员内部类和局部内部类
- 内部类字节码的命名方式 :外部类名$内部类名.class
成员内部类
- 概念:在一个类中的成员位置定义的类,被称为成员内部类
- 访问成员内部类
(1)格式:外部类名.内部类名 对象名=外部类对象.内部类对象
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
//成员内部类的定义格式
A.B b = new A().new B();
//调用成员内部类B的成员
System.out.println(b.Bnum);
b.methodB();
b.testB();
}
}
class A{
private int Anum = 20;
public void methodA(){
System.out.println("我是外部类方法");
}
public void testA(){
B b = new B();
System.out.println(b.Bnum);
b.methodB();
}
class B{
int Bnum = 30;
public void methodB(){
System.out.println("我是内部类方法");
}
public void testB(){
System.out.println(Anum);
methodA();
}
}
}
(2)修饰符:private:为了保证数据安全性;static:方便访问数据
(3)注意事项:
内部类一旦被private私有化,外界则不能创建内部类对象,只能通过在外部类中访问内部类,在外界通过访问外部类间接访问内部类,举个例子:
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
A a = new A();//创建外部类A对象
a.show();//访问外部类A成员方法
}
}
class A{
//将内部类B私有化
private class B{
int Bnum = 30;
public void methodB(){
System.out.println("我是内部类方法");
}
}
public void show(){
//创建内部类B对象
B b = new B();
//访问内部类B成员
System.out.println(b.Bnum);
b.methodB();
}
}
静态内部类访问的外部类类型必须静态修饰,举个例子:
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
//当内部类B被static静态修饰后,定义格式则更简洁
A.B b = new A.B();
b.methodB();
}
}
class A{
//外部类A的被使用成员必须用static静态修饰---------2
static int Anum = 10;
int num = 30;
public static void Amethod(){
System.out.println("静态修饰的外部类方法");
}
//静态修饰内部类B,只能访问外部类A的静态成员------1
static class B{
public void methodB(){
System.out.println(Anum);
//System.out.println(num); num非静态成员变量,不能访问
Amethod();
}
}
}
局部内部类
- 概念:在一个类中的局部位置定义的类,被称为局部内部类
- 访问局部内部类
(1)局部内部类不能直接在外界创建对象,要想访问,必须在内部类创建对象,然后通过这个对象调用局部成员,再在外界创建外部类对象,调用包含局部类的这个方法,即可访问局部内部类,跟成员内部类的私有化相似
(2)注意事项:局部内部类访问局部变量必须用final修饰
举个例子:
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
//创建外部类对象
Outer outer = new Outer();
//访问局部内部类成员
outer.Outermethod();
}
}
class Outer{
int num = 10;
public void Outermethod(){
//定义外部类局部变量
final int OuterNum = 20;
//在外部类的方法中,该内部类是局部内部类
class Inner{
public void Innermethod(){
//可以直接访问外部类的成员变量
System.out.println(num);
//访问外部类的局部变量,但这个变量必须用final关键字修饰
System.out.println(OuterNum);
}
}
//创建局部内部类对象
Inner inner = new Inner();
inner.Innermethod();
}
}
匿名内部类
- 概念:就是局部内部类的简化写法
- 本质:是一个对象,该对象继承了一个类或者实现了一个接口
- 格式:
new 类名或者接口名(){
重写方法;
};
- 方法调用
练习一:不使用匿名内部类完成抽象方法
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
Person person =new Student();
person.eat();
}
}
abstract class Person{
public abstract void eat();
}
class Student extends Person{
public void eat(){
System.out.println("吃饭");
}
}
运行结果:
可以看到,Student类在此处只被使用过一次,此时,就可以引入匿名内部类,起到一个简化代码的效果
使用匿名内部类完成抽象方法
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
Person person =new Person() {
@Override
public void eat() {
System.out.println("吃饭");
}
};
person.eat();
}
}
abstract class Person{
public abstract void eat();
}
看看运行结果:
从运行结果可知,输出结果是一样,但直接省略了一个类的编写,代码明显简洁了
练习二:用匿名内部类实现接口
package org.westos.demo2;
public class MyTest {
public static void main(String[] args) {
Myinterface myinterface = new Myinterface() {
@Override
public void eat() {
System.out.println("吃饭");
}
};
myinterface.eat();
}
}
interface Myinterface{
void eat();
}
运行结果:吃饭
由上述两个例子可以看出
只要一个类是抽象的或是一个接口,那么其子类中的方法就可以用匿名内部类来实现