Java(20)内部类
内部类
一个定义在另一个类里面的类称为内部类。内部类可以分为四种形式:成员内部类,
成员内部类
内部调用外部的属性和方法
成员内部类可以无条件访问外部类的所有成员属性和方法。
其他类(例子中的RunC类)访问一个内部类的形式有三种:
-
Outter.Inner outin=new Outter().new Inner();
-
Outter out=new Outter();
Outter.Inner in=out.new Inner();
-
public Inner getInnerInstance(){return Inner};
Outter out=new Outter();
Outter.Inner in=out.getInnerInstance();
public class Outter {
private String name = "Krystal";
private int age = 20;
private Inner innerInit=null;
public void outterFun(){
System.out.println("外部类的方法");
}
public Inner getInnerInstance(){
if(innerInit==null){
innerInit=new Inner();
return innerInit;
}else{
return innerInit;
}
}
class Inner {
void fun() {
//内部类无条件访问外部类的所有成员属性和方法,不需要声明
outterFun();
System.out.println(name);
System.out.println(age);
}
}
}
class RunC {
public static void main(String[] args) {
//第一种方式:
Outter.Inner outin=new Outter().new Inner();
outin.fun();
// //第二种方式:
// Outter out=new Outter();
// Outter.Inner in=out.new Inner();
// in.fun();
// //第三种方式:
// Outter out=new Outter();
// Outter.Inner in=out.getInnerInstance();
// in.fun();
}
}
/*运行结果为:
外部类的方法
Krystal
20
*/
外部调用内部的属性和方法
成员内部类可以无条件访问外部类的所有成员属性和方法,但是外部想访问内部就没那么简单了。首先要创建一个成员内部类的对象,然后通过该对象访问。
其他类(例子中的RunC
类)访问一个外部类的方式跟平时一样,正常调用即可。
public class Outter {
Inner in=new Inner();
void outterFun(){
System.out.println(in.salary);
in.innerFun();
}
class Inner {
public void innerFun() {
System.out.println("内部类的方法");
}
private long salary=25000;
}
}
class RunC {
public static void main(String[] args) {
Outter ot=new Outter();
ot.outterFun();
}
}
/*运行结果为:
25000
内部类的方法
*/
局部内部类
局部内部类是定义在一个方法内或者一个作用域内的类。局部内部类的访问权限仅限于方法内或者作用域内。
class Outter{
private String name="krystal";
public void outterFun(){
class Woman{
int age=18;
}
//方法内定义的局部内部类的成员属性和方法只能在该方法内使用
System.out.println(new Woman().age);
}
//Woman w=new Woman();--->编译报错
}
class RunC{
public static void main(String[] args) {
Outter out=new Outter();
out.outterFun();
}
}
//运行结果: 18
匿名内部类(常用)
首先来了解以下什么叫做匿名类,匿名类就是没有名称的类,匿名类的名称由java的编译器给出,格式形如:外部类名称+$匿名类顺序。
既然匿名类没有名称,没有名称就不能被其它地方引用,不能被实例化,所以匿名类只能用一次,也不能由构造器。
匿名类可以继承父类的方法,也可以重写父类的方法。
匿名类必须继承一个父类或者实现一个接口。创建语法格式如下:
new 父类构造器(实参列表) | 实现接口()
{
//匿名内部类的类体部分
}
匿名类可以访问外部类的成员属性和方法,匿名类的类体不可以声明static变量或static方法。
了解了匿名类之后,那么放在一个类内部的匿名类就是匿名内部类。
案例1:通过继承实体类创建匿名内部类
class Outter{
public String name="krystal";
void show(){
System.out.println("我叫"+name);
}
}
class RunC{
public static void main(String[] args) {
//通过实体类创建匿名内部类,相当于创建一个该类的子对象
Outter out=new Outter(){
//匿名内部类可以重写父类的方法:
@Override
void show() {
System.out.println("我叫Jimmy");
}
};
out.show();
//匿名内部类可以继承父类的属性和方法:
System.out.println(out.name);
//查看编译器分配给匿名内部类的名称
System.out.println(out.getClass());
}
}
/*运行结果为:
我叫Jimmy
krystal
class RunC$1
*/
案例2:通过实现接口创建匿名内部类
interface OutF{
public double getPrice();
public String getName();
}
class RunC{
public static void main(String[] args) {
OutF oF=new OutF() {
@Override
public double getPrice() {
return 153.45;
}
@Override
public String getName() {
return "shit";
}
};
System.out.println(oF.getName());
System.out.println(oF.getPrice());
System.out.println(oF.getClass());
}
}
/*运行结果为:
shit
153.45
class RunC$1
*/
静态内部类
静态内部类是定义在一个类内且加了static关键字的类。静态内部类不能访问外部类的非静态成员变量和方法,因为外部类的非static成员必须通过具体的对象来访问,如果静态内部类可以访问非static的外部类成员,就破坏了这一原则。
class staClass{
private String cls_id;
static class Innersta{
void fun(){
// System.out.println(cls_id);
// 报错Non-static field 'cls_id' cannot be referenced from a static context
}
}
}