内部类:
将一个类放在另一个类里或者方到另一个类的方法里,就是内部类,内部类分成4种:
成员内部类、局部内部类、匿名内部类、静态内部类:
成员内部类:
成员内部类可以无条件的访问外部类的属性与方法,但是如果外部类如果访问内部类的属性或者方法时需要实例化一个内部类对象,通过该对象访问内部类属性与方法:
内部类访问外部类属性或者方法:
public class Outer {
private String name="外部类";
void run() {
System.out.println("outerclass is running!");
}
class Inner{
private String code="自有属性";
void schedule() {
System.out.println(name);
run();
}
}
}
外部类访问内部类属性或者方法:
package org.pbccrc.org.pbccrc.innerclass;
public class Outer {
private String name="外部类";
void run() {
System.out.println("outerclass is running!");
}
void getInner() {
Inner inner=new Inner();
System.out.println(inner.code);
inner.schedule();
}
class Inner{
private String code="自有属性";
void schedule() {
System.out.println(name);
run();
}
}
}
外部类与内部类的属性名相同
public class Outer {
private String name="外部类";
void run() {
System.out.println("outerclass is running!");
}
void getInner() {
Inner inner=new Inner();
System.out.println(inner.code);
inner.schedule();
}
class Inner{
private String code="自有属性";
private String name="内部类";
void schedule() {
//如果调用外部类的需要使用外部类.this.属性
System.out.println(Outer.this.name);
//这个地方显示的是 内部类的属性
System.out.println(name);
run();
}
}
}
创建内部类
public class CreateInnerClass {
public static void main(String[] args) {
//创建内部类方式:
Outer outer=new Outer();
Outer.Inner inner= outer.new Inner();
}
}
class Outer {
private String name="外部类";
void run() {
System.out.println("outerclass is running!");
}
Inner getInnerClass() {
return new Inner();
}
void getInner() {
Inner inner=new Inner();
System.out.println(inner.code);
inner.schedule();
}
class Inner{
private String code="自有属性";
private String name="内部类";
void schedule() {
//如果调用外部类的需要使用外部类.this.属性
System.out.println(Outer.this.name);
//这个地方显示的是 内部类的属性
System.out.println(name);
run();
}
}
}
成员内部类对象创建一般是外部类.内部类 名称=外部类对象名.new 内部类(),因此内部类必须依赖外部类实例化对象才能创建;
public class PartClass {
public void runProcess () {
class Part{
private String nameString="局部内部类";
void process() {
System.out.println(nameString);
}
}
}
}
局部内部类,类前不能添加修饰符,像是局部变量;
匿名内部类:
public class ThreadAnonymous {
Thread thread =new Thread(new Runnable() {
@Override
public void run() {
System.out.println("运行一个匿名的线程!");
}
});
public static void main(String[] args) {
ThreadAnonymous test=new ThreadAnonymous();
test.thread.start();
}
}
package org.pbccrc.org.pbccrc.innerclass;
public class TeaTest {
public static void main(String[] args) {
drinkTea(new Tea() {
@Override
public void drink() {
System.out.println("i am drinking green tea");
}
});
}
public static void drinkTea(Tea tea) {
tea.drink();
}
}
interface Tea{
void drink();
}
注意:匿名内部类没有构造方法,只有匿名内部类没有构造方法,匿名内部类和局部内部类只能方法外部类中final的变量;
静态内部类
public class StaticInnerClass {
public static void main(String[] args) {
OuterStatic outerStatic=new OuterStatic();
outerStatic.process();
//静态内部类的使用
OuterStatic.InnerStatic innerStatic=new OuterStatic.InnerStatic();
innerStatic.getOuter();
}
}
class OuterStatic{
private int v=3;
private static final int a=9;
public void process() {
System.out.println("运行外部类的非static方法!");
}
public static void staticProcess() {
InnerStatic in=new InnerStatic();
System.out.println("访问到了静态内部类的属性"+in.b+in.c);
System.out.println("运行外部类的static的方法");
}
static class InnerStatic{
private final static int b=2;
private int c=4;
public void getOuter() {
System.out.println("get outter element"+a);
staticProcess();
}
}
}
总结:
1、静态内部类只能访问外部类的静态的属性与方法;
2、静态内部类属于外部类不属于外部类对象,因此在创建时不需要静态内部类的实例化对象绑定到外部类的实例化对象上;
3、一般的创建方式为
外部类.静态内部类 名称=new 外部类.静态内部类()
两个问题:
1、为什么使用内部类
解决了多继承的问题:内部类可以继承一个与外部类无关的类,保证了内部类的独立性,正是基于这一点,多重继承才能成为可能;
public interface Monster {
String hasWhat();
}
/**
* 它头脸像马、角像鹿、颈像骆驼、尾像驴
* @author caowenhua
*
*/
public class Milu {
void getDesc() {
System.out.println("mulu is "+new Lu().hasWhat()+":"
+new LuoTuo().hasWhat()+":"+new Horse().hasWhat()+":"
+new Lv().hasWhat());
}
class Lu implements Monster {
@Override
public String hasWhat() {
System.out.println("给你一双鹿角!");
return "鹿角";
}
}
class LuoTuo implements Monster{
@Override
public String hasWhat() {
System.out.println("给以骆驼的颈!");
return "骆驼颈";
}
}
class Horse implements Monster{
@Override
public String hasWhat() {
System.out.println("给以马的头脸!");
return "马头";
}
}
class Lv implements Monster{
@Override
public String hasWhat() {
System.out.println("给以驴的尾巴!");
return "驴尾";
}
}
public static void main(String[] args) {
Milu milu=new Milu();
milu.getDesc();
}
}
给你一双鹿角!
给以骆驼的颈!
给以马的头脸!
给以驴的尾巴!
mulu is 鹿角:骆驼颈:马头:驴尾
2、匿名内部类和局部内部类只能方法外部类中final的变量;为什么?
变量的生命周期导致的:
内部类与外部类一样是独立存在的不会因为定义在方法中会随着方法的消失而被销毁;在方法中定义的内部类,定义的局部变量会随着方法的消失而销毁,但是内部类对象仍然存在,那内部类对象引用了不存在的局部变量,就会报错,为解决这个问题会将内部类引用的局部变量复制一份作为内部的成员变量,这样当方法中局部变量死亡后,内部类扔可以使用“copy”版本的局部变量;
但是,将局部变量复制成内部类的成员变量时,如果在内部类中修改了成员变量是不是局部变量也要修改,所以就将局部变量定义成final,这样对他初始化后就不能改变,保证了局部变量与内部内的成员变量的一致性;
如果是成员变量是基本类型:则其值是不能改变的;
如果是引用变量的话,其引用的地址是不能改变的;
这就使得局部变量与内部类内建立的拷贝保持一致。
4705

被折叠的 条评论
为什么被折叠?



