接口与内部类
一、接口
1.接口格式
interface{}
接口中的成员修饰符是固定的。
成员常量:public staticfinal
成员函数:public abstract
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
接口:初期理解,可以认为是一个特殊的抽象类,当抽象类中的抽象方法都是抽象的,那么该类可以通过接口的形式来表示。
class用于定义类
interface用于定义接口。
接口中的方法必须全部抽象。
接口定义时,格式特点:
(1)接口常见定义:常量,抽象方法。
(2)接口中的成员都有固定修饰符。
常量:public staticfinal
方法:public abstract
记住:接口中的成员都是public的。
接口:是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化,否则子类只有一个抽象类。
接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。
接口的特点:
接口是对外暴露的规则。
接口是程序的功能扩展。
接口可以用来多实现。
类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。
接口与接口之间可以有继承关系。
2.接口的使用
接口(interface)是Java所提供的另一种重要功能,它的结构和抽象类非常相似。接口本身也具有数据成员与抽象方法,但它与抽象类有下列两点不同
接口的数据成员必须初始化。
接口里的方法必须全部都声明成abstract(默认),也就是说,接口不能像抽象类一样保有一般的方法,而必须全部是“抽象方法
为什么要使用接口?
类继承对于重用超类中的代码很有用,而Java只支持单继承,在遇到需要多继承的情况,可以通过接口来帮助实现。(多态性)
接口的方法可以不是继承链上的类中实现,从而为相互没有关系的类能实现同样功能的一组方法提供一种有效手段
3.接口的定义
[public] interface 接口名 extends 父接口名列表{
//声明常量字段
[public][static][final]<类型> 数据成员名=常量值;
//声明抽象方法
[public][abstract]<返回类型>方法名(参数表);
}
特点:
1、接口的访问控制修饰符只有public。
2、接口类型也可以继承,并且可以多重继承,使用extends。但它与类中的extends不同,它可以有多个父接口,各父接口间用逗号隔开
3、java的类层次结构中有一个顶级类Ojbect,接口没有
4、接口体内只能声明常量字段和抽象方法:接口中的所有常量必须是public static final,方法必须是public abstract,这是系统默认的,不管你在定义接口时,写不写修饰符都是一样的
4.接口的实现
<访问控制修饰符><修饰符>class类名[extends 父类名] implements 接口名表{
类体
}
1、实现接口可以是某个类的子类,也可以是父类。
2、一个类可以“实现”多个接口功能,从而实现多继承,关键词implements用于表示一个类实现若干接口,接口名之间用逗号隔开。
3、“继承”后的类可以抽象类也可以是普通类,若实现接口的类不是抽象类,则必须实现所有接口的所有方法,即为所有的抽象方法定义方法体
4、类中实现方法时,必须使用与该抽象方法完全一样的名字、返回类型和参数表,否则,就构成重载了。
二、内部类
1.内部类概念
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
2.访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
3.内部类的访问规则
1.内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类名.this
2.外部类要访问内部类,必须建立内部类对象。
4.访问格式
1.当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直接建立内部类对象。
格式:
外部类名.内部类名变量名=外部类对象.内部类对象;
Out.Inner in=new Outer().new Inner();
2.当内部类在成员位置上,就可以被成员修饰符所修饰。
比如:private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的。
3.当描述事物时,事物的内部还有事物,该事物用内部类来描述。
因为内部事物在使用外部事务的内容。
classBody
{
private class XinZang
{
}
public void show()
{
new XinZang().方法;
}
}
5.内部类定义在局部时
1.不可以被成员修饰符修饰
2.可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。
6.匿名内部类
1.匿名内部类其实就是内部类的简写格式。
2.定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3.匿名内部类的格式: new父类或者接口(){定义子类的内容}
例:
abstractclass AbsDemo
{
abstract void show();
}
newAbsDemo() //没有类名,用父类的名字
{
void show()
{
System.out.println("x=="+x);
}
}.show();
4.其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖,可以理解为带内容的对象。
5.匿名内部类中定义的方法最好不要超过3个。
三、总结
1.内部类
1,特点:
内部类可以直接访问外部类中成员。
外部类要访问内部类中的成员必须创建内部类的对象。
2,为什么要定义内部类?
类是用于描述事物的,而事物中还有具体的事物,而且这个内部的事物在访问者所属事物中的内容。这时这个内部的事物,也需要用类来描述,这个类就是内部类。
3,为什么内部类可以直接访问外部类中的成员。
因为内部类都持有一个外部类的引用,外部类名.this
4,内部类的修饰符:
当内部类定义在外部类的成员位置上时,可以使用成员的修饰符来进行内部类的修饰。
1,权限修饰符。
默认或者公有
可以直接这样访问内部类。
外部类名.内部类名变量名 = new外部类对象.new 内部类对象;
私有:是不可以直接在外部访问。
2,static修饰符。
内部类被静态修饰,出现访问局限性,只能访问外部类中的静态成员。
内部类被静态后,会随着外部类的加载而加载。
如果内部类中定义了静态成员,该内部类必须被静态修饰。
//访问静态内部类中的非静态成员。直接创建内部类对象。
外部类名.内部类名变量名 = new外部类名.内部类名();
//访问静态内部类中的静态成员。不需要对象。
外部类名.内部类名.内部类的静态成员
3,访问静态内部类中的静态成员
内部类被静态后,会随着外部类的加载而加载
直接 new内部类对象
访问静态内部类中的静态成员,不需要对象。
Outer.Inner.function();
如果内部类中定义了静态成员,该内部类必须被内部类修饰。
记住:内部类只有定义在成员的位置上,才具有这些修饰符。
4,内部类也可以定义在外部类中的局部位置上。
内部类定义在局部位置上不允许访问局部中变量。
只能按访问被final修饰的局部常量。
即使传递的变量也要加 final
2.匿名内部类
凡是匿名都是简写格式。
要定义匿名内部类,必须要有前提。
前提;内部类需要继承或者实现一个外部的类或者接口。
Demo 是一个外部抽象类
abstract Demo
{abstractvoid show(){}}
匿名内部类其实就是一个匿名子类对象,这个对象用{}结尾内部定义了成员。
也就是说是一个带有成员内容的对象,这个对象有点胖。
格式:new父类名或接口名().成员;
什么时候使用匿名内部类?
匿名内部类使用场景一:
当接口类型参数,该接口方法不超过三个,可以使用匿名内部类作为函数的参数进行传递。
3.内部类作用
在一个类(称为”外部类”)里定义另一个类是完全可以的,这称为“内部类”。使用内部类可以非常方便地编写事件驱动程序,例如图形用户界面程序。
内部类是一种非常有价值的特性,它能让你在逻辑上将相互从属的类组织起来,并且在类的内部控制访问权限。
内部类作为外部类的成员之一,可以直接访问外部类的其他成员。
外部类在其方法中,通过实例化内部类的一个对象才能访问内部类的成员。
4.内部类的使用
在方法和作用域里的内部类
内部类可以被创建在方法内部,甚至是任意一个作用域里。
两个理由:
1、多重继承:无论外部类是否已经继承了某个接口的实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。
2、你要处理一个复杂的问题,需要一个类,但是又不想让大家知道这个类
5.匿名内部类使用条件
匿名内部类就是没有名字的内部类。
如果满足下面的一些条件,使用匿名内部类是比较合适的:
a.只用到类的一个实例
b.类在定义后马上用到
c.类非常小(SUN推荐是在4行代码以下)
d.给类命名并不会导致你的代码更容易被理解
f.一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。