@TOC
前言
内部类是面向对象中类的比较复杂的一个成员,他最大的特点就是可以实现类与类的包含关系,可以直接访问类中的私有属性,是面向对象编程过程中简化思想的一种体现。
内部类⭐
一.定义及语法
🟠定义
🟤==一个类的内部完整嵌套了另一个类的结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类==
🟤语法:
class A{// 外部类
class B{//内部类
....
}
}
🔴内部类的分类:
1.局部内部类
2.匿名内部类
3.成员内部类
4.静态内部类
二.局部内部类
🟢内部类定义在外部类的局部位置,比如在==方法(或者代码块)中==
例如:
class A{
public void m1(){
class B{ //内部类B定义在A中的m1方法
.....
}
}
}
🟢内部类不能添加访问修饰符,它的本质是一个==局部变量==,但可以用final修饰,可以把它理解成
例如:
🟢作用域仅在定义它的局部位置(方法或者代码块)
🟢局部内部类可以直接访问外部类的成员
例如:
class A {//外部类
private int n1 = 100;
private void m2() { //外部类成员方法
System.out.println("m2被调用");
}
public void m1() {
System.out.println("m1方法被调用");
class B { //局部内部类
public void f1() {
//可以直接访问外部类的所有成员,包含私有的
System.out.println("n1=" + n1); //局部内部类访问外部类属性
}
}
}
}
🟢外部类访问局部内部类成员时,内部类中要先创建对象再访问
class A {//外部类
private int n1 = 100;
private void m2() {
System.out.println("m2被调用");
}
public void m1() {
System.out.println("m1方法被调用");
class B {//局部内部类
public void f1() {
System.out.println("f1方法被调用");
}
}
B b = new B(); //创建对象
B.f1();
}
}
🟢==外部其他类不能访问局部内部类(因为他是一个成员变量)==,当外部类和局部内部类成员重名时,内部类的访问遵循==就近原则==,若要访问外部类成员则须通过(外部类名.this.成员)来进行访问
例如:
就近原则的体现
class A{
private int n1=10;
public void m1(){
class B{
private int n1=20;
public void show(){
System.out.println(n1);
}
}
B b = new B();
b.show();
}
}
▶️运行结果:
利用this访问外部类成员
class A{
private int n1=10;
public void m1(){
class B{
private int n1=20;
public void show(){
System.out.println(A.this.n1); //访问外部类的 n1
}
}
B b = new B();
b.show();
}
}
▶️运行结果:
三.匿名内部类(🚩)
🟢匿名内部类是用来简化开发的,他并没有什么新颖的功能,只是能把复杂的问题简单化,比如在一个功能中,一个类(或者接口)之下我有很多子类要去继承(或者实现),按照常理,我需要一个一个子类地去写出来,并且实例化来调用类下的成员,但是使用匿名内部类,就不需要进行上述的重复操作,我只需要通过匿名内部类针对父类(或者接口)创建相应对象,在类内部重写方法即可.
定义在外部类的局部位置,比如方法(或者代码块)中,它具有一个特征没有类名,
语法:
class A{ // 外部类
public void m1(){
new 类或者接口(参数列表){// 匿名内部类
.....
}
}
}
🟢匿名内部类是一个类的定义,同时它本身也是一个对象,他同时具有类和对象的特征,因此可以用匿名内部类来调用方法
例如
class A{ // 外部类
public void m1(){
new B(){ // 匿名内部类
public void m2(){
......
}
}.m2()
}
}
🟢可以直接访问外部类的所有成员,包含私有成员
例如:
class A{
private int n1=10;
public void m1(){
new B(){
@Override
void play() {
System.out.println(n1);//访问外部属性
}
};
}
}
class B{
void play(){};
}
🟢匿名内部类可以直接访问外部类成员,包含私有
class A{
private int n1=10;
public void m1(){
new B(){
@Override
void play() {
System.out.println(n1);
}
};
}
}
class B{
void play(){};
}
🟢外部其他类不能访问匿名内部类,因为它是一个局部变量,作用域在定义它的方法或者代码块中
🟢外部类和内部类成员重名时,遵循就近原则访问,访问外部类成员通过(外部类名.this.成员)来访问
例如:
class A{
private int n1=10;
public void m1(){
new B(){
public int n1=100;
@Override
void play() {
System.out.println(A.this.n1);
}
};
}
}
class B{
void play(){};
}
==匿名内部类特性最经的典体现--------当作参数传递给对象==
public class EG {
public static void main(String[] args) {
new Cellphone().testWork(new PC() {
@Override
public double work(double n1, double n2) {
return n1+n2;
}
},10,4); //这是匿名内部类经典使用场景,作为参数传递给对象
}
}
interface PC{
double work(double n1,double n2);
}
class Cellphone {
public void testWork(PC pc,double n1,double n2){
double result=pc.work(n1,n2);
System.out.println("计算后的结果是:"+result);
}
}
四.成员内部类
🟢成员内部类定义在外部类的成员位置而不是方法(或者代码块)中,他和局部内部类很相似,但是区别在于它可以添加任意修饰符,因为它==本身就是一个成员==
例如:
class A {
private int n1 = 20;
public class B { //成员内部类
public void m1() { //可以添加任意修饰符
.......
}
}
}
🟢由于它是一个成员,所以他的作用域是整个类体,我在外部类成员方法中==直接创建成员内部类的对象调用它的方法就是很好的体现==
例如:
class A {
private int n1 = 20;
public class B { //成员内部类
public void m1() { //可以添加任意修饰符
.......
}
}
public void m2(){ //利用外部类A创建的方法来调用这个成员
new B().m1();
}
}
🟢成员内部类可以直接访问外部类成员
例如:
class A {
private int n1 = 20;
public class B { //成员内部类
public void m1() { //可以添加任意修饰符
System.out.println(n1);
}
}
}
🟢外部类创建对象再访问成员内部类,第二个例子已经展示
🟢外部类和内部类成员重名时,遵循就近原则访问,访问外部类成员通过(外部类名.this.成员)来访问,和上述类的方法一致
五.静态内部类
🟢静态内部类是定义在外部类的成员位置,并且有static修饰
它的性质和成员内部类基本一致,唯一不同的点在于,他虽然可以直接访问外部类的所有成员,但不能直接访问非静态成员
例如:
非静态成员n1和静态成员n2形成对比
默默地问一句:你累不累