内部类基础
在Java中支持在一个类中定义另一个类,这样的类称作内部类,而包含内部类的类称为内部类的外嵌类。广义上我们将内部类分为四种:成员内部类、静态内部类、局部(方法)内部类、匿名内部类。
//外嵌类
class outer{
//内部类
class Inter{
}
}
使用内部类的原因
在java中不能够实现多继承,而内部类具有类的基本特征(既可以继承父类又可以实现接口),这样就可以间接地解决类无法多继承地问题。
public class A extend B implements C{
public class D extends E implements F{
}
}
当然,内部类还有其他的优点:
//1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
//2、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
//3、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
//4、创建内部类对象的时刻并不依赖于外围类对象的创建。
//5. 外部类加载时并不需要立即加载静态内部类,内部类不被加载则不用去初始化,故而不占内存。
//6. 内部类的方法和成员属性可以与外嵌类相同,内部类具有独立的个体,可以使用访问权限隐藏内部类的实施细节,实现更好的封装。
public class InnerDemo2 {
class A{
private int a;
private void setA(int b){
a = b;
}
private int getA(){
return a;
}
}
public static void main(String[] args) {
InnerDemo2 inner = new InnerDemo2();
InnerDemo2.A a1 = new InnerDemo2().new A();
a1.setA(10);
System.out.println(a1.getA());
}
}
成员内部类
成员内部类是最普通的内部类,可以被任意权限修饰符修饰,具有类的基本特征,它可以直接访问外部类的成员。但是外部类想访问内部类的成员便需要先创建一个内部类的对象,再通过这个对象的引用进行放问。
创建内部类的对象有两种方法:
第一种方法如下面的代码所示,先声明一个内部类对象,然后在构造方法中创建内部类的对象的实例。
class RedCowForm{
static String formName;
RedCow cow;
RedCowForm(){
}
RedCowForm(String s){
cow = new RedCow(150,112,5000);
formName = s;
}
void showCowMess() {
cow.speak();
}
class RedCow{
String cowName = "红牛";
int height,weight,price;
RedCow(int h,int w,int p){
height = h;
weight = w;
price = p;
}
void speak() {
System.out.println("偶是"+cowName+",身高:"+height+"cm 体重:"+weight+"kg 生活在"+formName);
}
}
}
public class java7 {
public static void main(String[] args) {
RedCowForm form = new RedCowForm("红牛农场");
form.showCowMess();
form.cow.speak();
}
}
第二种则如下:
当内部类为非静态方法时
//外部类.内部类 内部类对象 = new 外部类().new 内部类();
当内部类为静态方法时
//外部类.内部类 内部类对象 = new 外部类.内部类();
需要注意的是:当成员内部类与外部类有同名的变量或方法时,外部类的同名方法或变量会被隐藏。
需要以下面的形式进行访问。
外部类.this.成员变量
外部类.this.成员方法
静态内部类
静态内部类也可以被任意的权限修饰符修饰,静态内部类不可以使用任何外部类的非static属性和方法
class Outer1{
private static String name = "test";
public static int age = 20;
static class Inner{
public static int num=10;
public void fun() {
System.out.println(name);
System.out.println(age);
}
}
}
public class outDemo3 {
public static void main(String[] args) {
}
}
方法内部类
方法内部类也叫局部内部类,存在与方法之中,不能被访问权限修饰符修饰。
class E{
Outer.Inner inner = new Outer.Inner();
void show(Outer o){
inner.A();
o.A();
}
}
class Outer{
int b=10;
public void A(){
System.out.println("外部类");
}
public void E() {
final int n=10;
class K{
public static int AB(int a){
a=n;
return a;
}
}
System.out.println(K.AB(20));
}
static class Inner{
static int a;
public static void B(){
System.out.println("内部类");
}
public void A(){
System.out.println("内部类");
}
}
}
public class InnerDemo1 {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
Outer outer = new Outer();
outer.A();
inner.A();
E e = new E();
e.show(new Outer(){
public void A(){
System.out.println("A");
}
});
e.show(outer);
Outer.Inner.B();
outer.E();
}
}
匿名内部类
匿名内部类应该是平时我们编写代码时用得最多的,使用匿名内部类不但方便,而且使代码更加容易维护。
public class Demo {
private Runnable runnable = new Runnable() {
@override
public void run() {}
}
}