JAVA 中的内部类详解

用户头像
倔强的攻城狮
关注
发布于: 2020 年 10 月 13 日
JAVA中的内部类详解

内部类包含两种:静态内部类非静态内部类



一. 静态内部类:

class OuterClass {
...
static class StaticNestedClass {
...
}
}

特点:

①能访问外部类OuterClass的静态成员(属性和方法),不能直接访问外部类OuterClass的实例成员(属性和方法)。

②静态内部类StaticNestedClass允许定义静态成员(属性和方法)和 实例成员(属性和方法)



静态内部类使用:

OuterClass.StaticNestedClass

创建一个静态内部类的对象

OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();






二. 非静态内部类

class OuterClass {
...
class InnerClass {
...
}
}

特点:

①能访问外部类OuterClass的静态成员,静态方法 和 实例成员,实例方法。

②只能定义实例成员(属性和方法) 不能定义静态成员(属性和方法)



非静态内部类的使用:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

必须先创建一个外部类的实例,然后才能创建非静态内部类。






两种特殊的非静态内部类:局部类匿名类



在方法中声明类,这些类称为“局部类

例子: 验证两个电话的合法性。定义了一个局部类PhoneNumber。

局部类只可以访问外部类的静态成员(属性和方法) , 局部类不能定义静态成员(属性和方法) ,除特殊的公共静态的常量。如 public static final String = "123"

public class LocalClassExample {
static String regularExpression = "[^0-9]";
public static void validatePhoneNumber(
String phoneNumber1, String phoneNumber2) {
final int numberLength = 10;
class PhoneNumber {
String formattedPhoneNumber = null;

PhoneNumber(String phoneNumber){
// numberLength = 7;
String currentNumber = phoneNumber.replaceAll(
regularExpression, "");
if (currentNumber.length() == numberLength)
formattedPhoneNumber = currentNumber;
else
formattedPhoneNumber = null;
}

public String getNumber() {
return formattedPhoneNumber;
}
}

PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1);
PhoneNumber myNumber2 = new PhoneNumber(phoneNumber2);

if (myNumber1.getNumber() == null)
System.out.println("First number is invalid");
else
System.out.println("First number is " + myNumber1.getNumber());
if (myNumber2.getNumber() == null)
System.out.println("Second number is invalid");
else
System.out.println("Second number is " + myNumber2.getNumber());

}

public static void main(String... args) {
validatePhoneNumber("123-456-7890", "456-7890");
}
}

结果如下:

First number is 1234567890
Second number is invalid






在方法中声明一个没有名字的类, 这些类称为“匿名类

匿名类是一个表达式,类似于调用构造方法,并伴随着类的代码块的定义。

例子: 使用匿名内部类初始化局部变量frenchGreeting和spanishGreeting



public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
HelloWorld spanishGreeting = new HelloWorld() {
String name = "mundo";
public void greet() {
greetSomeone("mundo");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hola, " + name);
}
};
englishGreeting.greet();
frenchGreeting.greetSomeone("Fred");
spanishGreeting.greet();
}

public static void main(String... args) {
HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}





三. 重影:

例子:

当定义变量的时候,有可能你的变量名在当前外部类或内部类或方法中重复,以下例子帮你正确使用某个范围内的变量。

public class ShadowTest {

public int x = 0;

class FirstLevel {

public int x = 1;

void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}

public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}

结果如下:

x = 23
this.x = 1
ShadowTest.this.x = 0

当你访问FirstLevel实例变量x,则使用 this.x 。

当你想要访问更大范围的变量x, 则使用ShadowTest.this.x 代表使用ShadowTest实例的变量x 。



用户头像

倔强的攻城狮

关注

脚踏实地才能走的更远,知其然,知其所以然. 2020.09.27 加入

从事于互联网+同城速递行业, 岗位使用的语言为java, 此次写作的主要目的是从java基础深入浅出,逐渐掌握所有java模块的技能, 包括并发,IO, NIO, Lambda 表达式等内容让大家知其然知其所以然。

评论

发布
暂无评论
JAVA中的内部类详解