接口:
1、广义:一切定义规则的事物都是接口
2、狭义:Java中用于定义方法声明的规则就是接口,Java的接口中,定义的所有方法都是抽象方法
3、好处,将方法的调用和方法的实现分离开,可以降低代码耦合度,提高开发效率
接口的特点
1、关键字interface
2、格式:
interface 接口名{
}
3、接口中,只能声明定义抽象方法,不能定义有方法实现的方法
4、接口的实现
class 类名 implements 接口名{
}
接口中只有规则没有实现方法,我们通过类去添加规则的实现,不同的类可以实现相同的接口,给予接口不同的实现
5、接口不能实例化(不能创建对象);
【都是通过类来实现接口的,类可以调用对象,将来通过创建接口的实现类的对象,对象来调用实现了的方法】
public static void main(String[] args) {
//接口的引用指向实现了的对象
MyInter1 my1 = new Inter1Zi();
MyInter1 my2 = new Inter2();
my1.test1();//Inter1实现了接口
my2.test1();//Inter2实现了接口
}
}
interface MyInter1 {
public abstract void test1();
public abstract void test2();
}
abstract class Inter1 implements MyInter1 {
@Override
public void test1() {
System.out.println("Inter1实现了接口");
}
}
class Inter1Zi extends Inter1 {
@Override
public void test2() {
}
public void show() {
System.out.println("!!!!!!!1");
}
}
class Inter2 implements MyInter1 {
@Override
public void test1() {
System.out.println("Inter2实现了接口");
}
@Override
public void test2() {
}
}
类与类,类与接口,接口与接口之间的关系
1、类与类是继承关系【extends】支持单继承,多层继承,不支持多继承
2、类与接口是实现关系【implements】支持单实现,多实现,不存在多层实现(接口一旦被类实现,就变成了类与类的关系)
1、单实现:
class 类名 implements 接口名 {
实现接口中所有的抽象方法
}
2、多实现:
class 类名 implements 接口1, 接口2, 接口3, …, 接口n {
实现接口中所有的抽象方法
}
此格式不存在安全隐患。就算多个接口中有同名方法,但是在同一个实现类中,能对 应到的方法体只有一个,不会和别的方法体起冲突,所以没有安全隐患。
3、一个类在实现多个接口的同时还能继承一个类:
class 子类类名 extends 父类类名 implements 接口1, 接口2, 接口3, …, 接口n {
实现接口中所有的抽象方法
重写父类中继承来的方法
}
3、接口与接口是继承关系,使用extend关键字【类相当于亲爹,接口相当于干爹】
(1)支持单继承,支持多继承,支持多层继承
(2)接口的多继承格式:
interface 接口1 extends 接口1, 接口2, 接口3, …, 接口n {
相当于整合了声明上所有接口的抽象方法
}
public static void main(String[] args) {
myinter my1 = new interzi(); //接口引用指向实现类【多态】
myinter my2 = new inter2();
my1.test1();
my2.test1();
}
interface myinter{ //定义了一个myinter接口
public abstract void test1(); //给接口内写如抽象方法
public abstract void test2();
}
abstract class inter1 implements myinter{ //创建一个实现类 myinter 的实现类inter1【因为实现类中不能实现接口的全部方法,
//所以创建为抽象类】
public void test1(){ //类对于抽象方法的重写
System.out.println("inter1实现了");
}
}
class interzi extends inter1{ //给实现类inter1创建一个interzi子类
public void test2(){ //因为继承原因,interzi子类有父类的text1方法,故再重写一个text2的方法以至于可以满足接口所
//有实现方法,不用写抽象类,从而可以创建对象
}
}
class inter2 implements myinter{ //创建一个实现类myinter的实现类inter2【因为实现类中能实现接口的全部方法,
//所以不用创建抽象类】
public void test1() { //在实现类 2中重写test1()test2()方法
System.out.println("inter2实现了");
}
public void test2() {
}
}
接口中成员的特点
1、没有成员变量,只能定义常量,建议手动加上public static final,
2、没有构造方法,
3、成员方法只能是抽象方法,方法的声明可以省略public abstract,建议手动加上
public static void main(String[] args) {
}
interface MyInter2 {
public static final int num = 10;//常量
public abstract void test();
}
class Inter3 {
void test() {
}
}
内部类
定义在类的内部的类。和方法、变量等,均作为类的成员。
1、根据定义位置不同,可以分为:
1)成员内部类
<1>普通成员内部类 <2>私有成员内部类 <3>静态成员内部类
2)局部内部类
3、根据表示方式不同:
1、有名字的内部类
2、匿名内部类
普通成员内部类
1、定义在类成员位置的类,就是成员内部类
2、格式
class 外部类类名{
外部类成员
class 内部类类名{
内部类成员
}
}
3、成员内部类的说明:
1)内部类可以直接访问外部类中的所有成员
2)外部类中,不能直接访问内部类的成员,必须通过在外部类中创建内部类的对象才可以访问
3)在外部类以外访问内部类成员们可以创建外部类对象,对象调用外部类方法,方法中通过内部类访问内部类成员,从而达成间接访问
4)在外部类以外访问内部类的成员,可以直接创建内部类对象:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
public static void main(String[] args) {
//外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
Body1.Heart bh = new Body1().new Heart();//创建内部类对象
System.out.println(bh.color);//不能访问私有成员变量
}
}
class Body1 {
private int length = 175;//私有
int age = 10;
class Heart {//创建内部类
String color = "黑色";
private int weight = 80;
public void show() {
System.out.println(age);
System.out.println(length);
}
}
Heart h = new Heart();//在外部类创建内部类的对象
public void test() {
System.out.println(age);
System.out.println(h.color);
System.out.println(h.weight);
}
}
私有内部类
在普通成员内部声明加上private关键字
格式:
class 外部类类名 {
外部类成员
private class 内部类类名 {
内部类成员
}
}
静态成员内部类
格式:
class 外部类类名 {
外部类成员
static class 内部类类名 {
内部类成员
}
}
2、访问特点:
(1)静态成员内部类是外部类的静态成员
(2)在静态成员内部类中,访问外部类成员,外部类成员如果是静态的就按照静态访问,非静态就按照非静态访问
(3)在外部类中,访问静态成员内部类的内容,也要按照静态按照静态访问,非静态按照非静态访问
(4)总结:访问的内容,到底用静态方式还是非静态方式,不取决于类本身是否为静态,而是取决于要访问的内容本身是静态还是非静态
(5)在外部类以外创建静态成员内部类的格式:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
局部内部类
1、定义在方法中的类
2、访问说明:方法中的局部变量在方法外不能被访问,局部内部类与局部变量同作为方法中的成员,也在方法外不能被访问。所以局部内部类在方法以外没有任何手段内被访问。
3、解决方式:只能执行局部内部类所在方法,在方法中创建局部内部类对象,对象调用类中方法,一并执行
匿名内部类
使用场景:1、实现抽象类,2、实现接口
格式:
new 抽象父类名称或接口名称(){
要实现的抽象方法
}
本质上是一个实现类的对象,编译过后会形成一个类文件