抽象类
包含有抽象方法的类或被abstract修饰的类
abstract class 类名 {}
public abstract void eat();//声明
抽象类不能直接实例化(不能直接NEW但可以间接实例化):
抽象类类型 引用 = new 具体子类();
抽象类的子类
可以是抽象类,(子类没有覆盖抽象父类中,所有的抽象方法)
也可以是具体类(子类必须覆盖抽象父类中,所有的抽象方法)
抽象类的成员特点:
构造方法:同普通类
成员变量:同普通类
成员方法:
抽象方法:仅仅只是为了声明类中有这样的行为,无法确定行为的实现。
非抽象方法:做一个代码复用。
注意事项
abstract不与private、final、static共存
抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
接口
语法
接口用关键字interface表示
格式:interface 接口名 {}
在Java语言中Interface也可以表示一种类型
a、类和接口都可以用来表示一种数据类型,地位等同
b、类定义的是一个数据集合基于这个数据集的一组操作(行为),类所描述的这一组行为,他们是有关系的(间接),都可以访问一个数据集合
c、接口表示数据类型,侧重于描述一组特殊功能的行为,这些行为,可以完全没有任何关系,接口中的方法,他们的关系比较松散
类实现接口用implements表示
类和接口可以有实现关系,实现关系实质上是一种继承关系
格式:class 类名 implements 接口名 {}
接口不能直接实例化
间接实例化:
接口类型的引用=new 接口实现子类();
接口的子类,可以是抽象类也可以是具体类
特点
无构造方法
成员变量:只能是常量,修饰符public static final
成员方法:只能是抽象方法,修饰符public abstract
接口与抽象类
- 成员区别:
1、抽象类: 变量;有抽象方法; 非抽象方法
2、接口 :静态常量;抽象方法 - 关系区别:
1、类与类: 继承,单继承
2、类与接口: 实现,单实现,多实现
3、接口与接口: 继承,单继承,多继承 - 设计理念区别:
1、抽象类 被继承体现的是:”is a”的关系。共性功能
2、接口 被实现体现的是:”like a”的关系。扩展功能
接口中的方法
静态方法:调用方法(不在定义静态方法的接口类中:接口名.方法)
作用:作为工具方法
默认方法:可以当成普通类中默认方法,子类中的方法可以覆盖接口中的默认方法
作用:是一种妥协,接口中增加一个方法
这两种方法的默认访问权限都是public
内部类
- 定义在其他类内部的类就称为内部类
1、成员位置(成员内部类)
2、局部位置(局部内部类):定义在类中方法体中的类,只能在该类的方法体中才能被访问,可以在局部内部类中访问方法体中的局部变量 - 内部类的访问:
- 在外部类的外部,创建一个内部类对象:外部类名.内部类名.对象名=外部类对象.内部类对象;
//创建
MemberOuter.MemberInner inner = new MemberOuter().New MemberInner();
class MenberOuter{
class MemberInner{}
}
-静态的成员位置内部类:不依赖与外部类而存在,可以直接访问
创建对象的方法:
//创建
MemberOuter.MemberInner inner = new MemberOuter.MemberInner();
class MenberOuter{
static class MemberInner{}
}
- 局部内部类
局部内部类对象的创建要简单的多,因为局部内部类只能在该类的方法体中才能被访问。
内部类的访问特点
内部类可以直接访问外部类的成员,包括私有。
外部类要访问内部类的成员,必须创建对象。
外部类名.内部类名 对象名 = 外部类对象.内部类对象;
成员内部的常见修饰符
private
保证成员位置内部类只对其外部类可见
static
外部类名.内部类名 对象名 =new 外部类名.内部类名();
访问特征
static和非static方法
匿名内部类对象
不管是成员或局部位置内部类,我们要使用内部类都分成了2步:
1、定义内部类
2、创建内部类对象
通过定义匿名内部类对象,我们可以将上面的2步变为1步(前提是存在一个类或者是接口)
new 类名或者接口名() {重写方法;};//是一条语句,末尾加‘;’
由于没有给该对象指明引用变量,导致当前执行一次后无法再次执行该对象,因为找不到了,变成垃圾,被垃圾回收机制处理掉。
a、可以通过引用变量复用对象,多次在对象上调用方法。
eg:
类名或者接口名 标签=new 类名或者接口名() {重写方法;};
接口(匿名)
只需要执行一次的接口,用匿名内部类的方法方便
当返回的是接口类型的子类对象
return new 接口名(){};
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
//类名.this这种写法和静态没有任何关系,只是表达this的嵌套层级
System.out.println(Outer.this.num);
//利用this访问内部类中的同名成员变量
System.out.println(this.num);
//直接通过变量名,访问内部类中同名的局部变量
System.out.println(num);
}
}
}
//在控制台分别输出10,20,30