内部类: 定义在一个类或者方法内的类称为内部类。
内部类主要分为:成员内部类、局部内部类、静态内部类、匿名内部类四种。
特性:
1.非静态内部类默认持有外部类的引用,所以在使用内部类对象时需要首先创建外部类的对象。
2.外部类需要使用内部类时首先需要创建内部类的对象。
优点:
1.在java中一个类可以实现多个接口但只能继承一个抽象类,内部类的出现使得多继承的方案变的完整
2.方便统一的将存在一定逻辑关系的类组织起来,优化代码结构。
3.提高代码的封装性,隐藏内部具体的实现。
成员内部类: 没有使用static修饰,可以有自己的访问修饰符。
特点:
1.可以直接使用外部类的成员变量和方法,包括私有方法与变量。
public class Test {
private final String TAG="test";
private int A=1;
public String B="a";
private void getType(){
Log.d(TAG, "外部类方法");
}
public class TestA{
public void getTest(){
//打印外部类私有成员变量
Log.d(TAG, String.valueOf(A));
//打印外部类公有成员变量
Log.d(TAG, B);
//直接使用外部类方法
getType();
}
}
}
public class MainActivity extends AppCompatActivity {
private final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建外部类Test对象,在使用成员内部类时首先要创建外部类的对象
Test test =new Test();
//调用Test类中的内部类TestA的方法
test.new TestA().getTest();
}
}
2.在内部类使用与外部类相同的成员变量和方法外部类会发生隐藏情况,或者在内部类中创建外部类的对象调用外部类的方法与变量。
public class Test {
private final String TAG="test";
private int A=1;
public String B="a";
public void getType(){
Log.d("外部类getType", String.valueOf(A));
}
public class TestA{
//外部类与内部类变量名相同
private int A=2;
//外部类与内部类方法名相同
public void getType(){
Log.d("内部类getType", String.valueOf(A));
}
}
}
public class MainActivity extends AppCompatActivity {
private final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Test test =new Test();
//调用内部类的方法时隐藏了外部类相同的方法与变量
test.new TestA().getType();
}
}
3.不能含有static修饰的变量和方法,因为成员内部类必须先创建外部类的对象才可以创建其自身
4.外部类调用内部类中的方法时需要创建内部类的对象并调用方法
.
.
.
局部内部类: 定义在类的方法中,没有访问修饰符,只能访问外部方法final修饰的变量,作用域为当前方法。
public class Test {
private final String TAG="test";
private int A=1;
public String B="a";
public void getType(){
Log.d("外部类getType方法", String.valueOf(A));
//定义在方法内
class TestA{
private int A=2;
public void getType(){
Log.d("局部内部类getType", String.valueOf(new Test().A));
}
}
//调用局部内部类中的方法
new TestA().getType();
}
}
public class MainActivity extends AppCompatActivity {
private final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//调用外部类getType方法
Test test =new Test();
test.getType();
}
}
.
.
.
匿名内部类: 可以理解为没有名字的内部类,没有访问修饰符,没有构造器,匿名内部类只能被访问一次所以可以用匿名内部类来实现那些只被使用一次的类,减少不必要的类文件的创建。使用匿名内部类必须继承接口或父类,常用于接口回调。
例:
public class MainActivity extends AppCompatActivity {
private final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//可以使用匿名内部类的方式来创建一个子线程
new Thread(){
@Override
public void run() {
super.run();
}
};
}
}
.
.
.
静态内部类: 定义在类的内部,使用static修饰的类被称为静态内部类。
特点:静态内部类可以使用外部类static修饰的成员变量和方法。
静态内部类依赖于外部类而不是外部类的对象
public class Test {
private final String TAG="test";
private static int A=1;
public String B="a";
//静态内部类
public static class TestA{
//静态方法
public static void getStaticType(){
Log.d("静态内部类静态方法", String.valueOf(A));
}
//非静态方法
public void getType(){
Log.d("静态内部类非静态方法", String.valueOf(new Test().B));
}
}
}
public class MainActivity extends AppCompatActivity {
private final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//调用静态内部类的非静态方法需要创建内部类的对象
new Test.TestA().getType();
//调用静态内部类的静态方法,静态内部类属于外部类而不是外部类的对象
Test.TestA.getStaticType();
}
}