内部类(Inner Class)
内部类的定义:
在Java中,允许在一个类的内部定义类,这样的类称作内部类也叫做嵌套类, 这个内部类所在的类称作外部类。
内部类的创建:
语法: 外部类名.内部类名 变量名=new 外部类名().new 内部类名();
举例: 假设A是外部类,B是内部类
A.B b=new A().new B();
建立内部类对象时应注意:
1.在外部类的内部可以直接使用inner s=new inner();(因为外部类知道inner是哪个类,所以可以生成对象。)
2.在外部类的外部,要生成(new)一个内部类对象,需要首先建立一个外部类对象(外部类可用),然后在生成一个内部类对象。
内部类的表现形式:
1.静态内部类
2.成员内部类
3.方法内部类
4.匿名内部类
内部类的共性:
1.内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类命和$符号。
2.内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。
内部类的优点:
1.内部类成员可以直接访问外部类的成员(包括私有成员)。
2.比类具有更好的封装性
基本形式:
public class Outer1 {
public class Inner{
}
}
例子:
(1).public class Outer {
private int num=4; //定义成员变量
public void test(){
Inner inner =new Inner();
inner.show();
}
//下面的代码定义了一个成员内部类
class Inner{
void show(){
//在成员内部类的方法中访问外部类的成员变量
System.out.println("num="+num);
}
}
}
public class Example {
public static void main(String[] args){
Outer.Inner inner =new Outer().new Inner(); //创建内部类对象
inner.show(); //调用test()方法
}
}
(2).public class Myclass {
public Myclass() {
System.out.println("产生MyClass");
}
class M {
public M() {
System.out.println("产生M");
}
}
public static void main(String[] args) {
Myclass my = new Myclass();
// 内部类相当于外部类的属性,内部类对象的产生要依赖于外部类对象,只要是属性可以有的修饰符都可以修饰内部类。
// 内部类在编译时同样会产生class文件。命名为:外部类名$内部类名.class
Myclass.M m = my.new M();
}
}
匿名内部类(Anonymous Inner Class)
匿名内部类的定义:
没有名字的内部类。表面上看起来那是它的名字,实际上不是它的名字。
使用匿名内部类的前提:
必须继承父类或实现一个接口
匿名内部类的分类:
1.继承式的匿名内部类
2.接口式的匿名内部类
3.参数式的匿名内部类
特点:
匿名内部类一定是跟在new的后面,用其隐含实现一个接口或一个类,没有类名,根据多态,我们使用其父类名。因为匿名内部类属于局部类,所以局部类的所有限制对其生效。匿名内部类是唯一一种无构造方法的类。匿名内部类在编译时,系统自动起名Out$1.class。如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。
注意点:
1.不能有构造方法
2.不能定义任何静态成员、方法或类
3.不能是public,protected,private,static。
4.只能创建匿名内部类的一个实例。
匿名内部类的优点:
可以使命名变得简洁
使代码更加紧凑,简洁,封装性比内部类更优
一个类用于继承其他类或是实现接口,无需增加其他的方法,只是对继承方法实现 覆盖。
匿名内部类的缺点:
可读性差
例子:
(1).public class Dog { //建立一个Dog类
static abstract class Ball { //建立一个抽象类
abstract String getName(); //建立一个抽象方法,抽象方法必须用abstract来修饰
}
void play(Ball b){
System.out.println(b.getName());
}
public static void main(String[] args){
Dog dog = new Dog();
dog.play(new Ball(){ //匿名内部类实现抽象方法getName();
@Override
String getName() {
return "qiu qiu";
}});
}
}
(2).
public interface Product {
public double getPrice();
public String getName();
}
public class TestAnonymous {
public void test(Product p){
System.out.println("我购买了一个"+p.getName()+",花掉了"+p.getPrice());
}
public static void main(String[] args){
TestAnonymous ta=new TestAnonymous();
//调用test方法,需要传入一个Product参数,此处传入其匿名,实现类的实例
ta.test(new Product(){
public double getPrice(){
return 40;
}
public String getName(){
return "水晶球";
}
});
}
}
//以上的匿名内部类相当于
/*
class AnonymousProduct implements Product //implements是实现接口的关键字
{
public double getPrice(){
return 40;
}
public String getName(){
return "水晶球";
}
}
ta.test(new AnonymousProduct());
*/