类的五大成员: 属性,方法,构造器,代码块,内部类
一、局部内部类
声明名在外部内的方法或代码块中,局部内部类可以直接使用外部内私有的属性,可以声明自己局部内部类的属性和方法,跟外部类一样可以由类的五大成员变量变量组成,不能添加访问修饰符,因为局部内部类的地位等同于局部变量。局部变量是不能使用修饰符的;当内部类和外部内有同名属性时,访问这个属性会遵循就近原则,若需要访问外部类同名属性,可以使用外部类名.this.属性名进行访问;局部内部类不能被外部内new,只能在当前方法中使用。
代码示例:
package com.example.springdemo.study.内部类;
/**
* @author zhangsm
* @since 2023/12/26
*/
public class Student {
private String name = "张三";
private String age;
public void printStudentName() {
class Jack {
String name = "李四";
public void printJack() {
//访问内部类的name
System.out.println(this.name);
//访问外部类name
System.out.println(Student.this.name);
}
}
Jack jack = new Jack();
jack.printJack();
}
}
class TestStudent {
public static void main(String[] args) {
new Student().printStudentName();
}
}
二、匿名内部类
匿名内部类只会被创建一次,也能只能被使用一次,使用完后就会被销毁;
代码示例:
package com.example.springdemo.study.匿名内部类;
/**
* @author zhangsm
* @since 2023/12/26
*/
public class AnonymousClassDemo {
public static void main(String[] args) {
new OuterClass().anonymousClass();
}
}
interface MyAnimal {
MyAnimal eat();
void smile();
}
//外部类
class OuterClass {
public void anonymousClass() {
//匿名内部类
new MyAnimal() {
@Override
public MyAnimal eat() {
System.out.println("小狗吃骨头");
System.out.println(this);
return this;
}
@Override
public void smile() {
System.out.println("小狗在微笑");
System.out.println(this);
}
}.eat().smile();
//打印可得到真实的匿名内部类的编译类型为MyAnimal$1
// System.out.println(myAnimal.getClass());
}
}
PS:经典使用场景,作为入参传递
代码示例:
public class AnonymousClassDemo {
public static void main(String[] args) {
new OuterClass().anonymousClass();
}
}
interface MyAnimal {
MyAnimal eat();
void smile();
}
//外部类
class OuterClass {
public void testAnonymousClass(MyAnimal myAnimal) {
System.out.println(myAnimal.eat());
}
public void test() {
testAnonymousClass(new MyAnimal() {
@Override
public MyAnimal eat() {
System.out.println("测试匿名内部类入参重写eat");
System.out.println(this);
return this;
}
@Override
public void smile() {
System.out.println("测试匿名内部类入参重写smile");
System.out.println(this);
}
});
}
}
三、成员内部类
声明在外部类中,可以看成是一个外部类的成员变量,因此成员内部类是可以用访问修饰符进行修饰的,访问规则跟外部类一致;成员内部类也可以定义自己的类的五大成员;当内部类和外部内有同名属性时,访问这个属性会遵循就近原则,若需要访问外部类同名属性,可以使用外部类名.this.属性名进行访问;当成员内部类的访问权限允许的条件下,是可以被外部类new的。
代码示例:
/**
* 1.局部内部类只能被当前方法使用,不能用访问修饰符修饰->局部内部类可以定义在方法里也可以是匿名内部类
* 2.
*
* @author zhangsm
* @since 2023/12/21
*/
//外部类
public class Other {
private String name = "张三";
//静态成员内部类
public class A {
public int a = 1;
//内部类的内部类
protected class B {
//Other.A.B的实例方法print()
public void print(){
System.out.println("hhhhhhh我是嵌套的成员内部类");
}
}
}
//Other的实例方法print()
public void print() {
class C {
private String name = "李四";
public void CPrint() {
System.out.println("我是局部内部类");
}
public void CPrint2() {
System.out.println(Other.this.name);
System.out.println(this.name);
}
}
new C().CPrint2();
}
}
class Test{
public void main(String[] args){
//创建成员内部类实例的方式
Other.A a = new Other().new A();
Other.A.B b = new Other().new A().new B();
//使用成员内部类的方法
b.print();
}
}
四、静态内部类
静态内部类定义在类的成员位置,关键字static修饰i,静态内部类可以直接访问外部类的静态成员属性和静态方法(包括私有的静态属性和私有的静态方法),但不能直接访问非静态的成员属性和非静态方法,需要创建一个外部的类实例对象才能够对其进行访问。作用域为整个外部类类体。当静态内部类被声明为私有的时候,是无法像普通的私有变量一样提供一个公共方法方法访问到的(可尝试把示例代码的静态内部类声明为private)
代码示例:
package com.example.springdemo.study.静态内部类;
/**
* @author zhangshunmin
* @since 2023/12/27
*/
public class OuterClass {
private String name = "张三";
private static int age = 10;
static class StaticInnerClass {
public void print() {
//直接访问非静态属性报错
// System.out.println(name);
//编译通过
System.out.println(age);
OuterClass outerClass = new OuterClass();
System.out.println(outerClass.name);
}
}
public static StaticInnerClass getStaticInnerClass(){
return new getStaticInnerClass();
}
}
//外部其他类
class Test {
public static void main(String[] args) {
OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass();
staticInnerClass.print();
//当静态内部类被声明为私有的时候下面代码报错;
// OuterClass.StaticInnerClass staticInnerClass2 = OuterClass.getStaticInnerClass();
}
}