一.抽象类
1.基本概念
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,它的作用有点类似“模板”,其目的是根据它的格式来创建和修改新的类。
语法:
abstract class 抽象类名称 {
// 抽象方法:被abstract修饰的方法,没有方法体
abstract public void 方法名称();
// 抽象类也是类,也可以增加普通方法和属性
}
注:抽象类内部可以包含普通方法和属性,以及构造方法。
2.抽象类的特性
1.抽象类不能直接实例化
abstract class Animal {
public abstract void bark();
}
public class Test {
public static void main(String[] args) {
Animal a = new Animal();
}
}
编译出错:
Animal是抽象的; 无法实例化
2.抽象方法不能是private
abstract class Animal {
private abstract void bark();
}
编译出错:
非法的修饰符组合: abstract和private
注:抽象方法没有加访问限定符时,默认是public
3.因为抽象方法要被子类重写,所以不能被final和static修饰
abstract class Animal {
public abstract static void bark();
public abstract final void eat();
}
编译出错:
非法的修饰符组合: abstract和static
非法的修饰符组合: abstract和final
- 抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修饰
abstract class Animal {
public abstract void bark();
}
class Dog extends Animal{
}
编译出错:
Dog不是抽象的, 并且未覆盖Animal中的抽象方法bark()
- 抽象类中不一定包含抽象方法,但是有抽象方法的类一定是抽象类
- 抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
实现代码
abstract class Animal {
public abstract void bark();
}
class Dog extends Animal{
@Override
public void bark() {
System.out.println("汪汪.....");
}
}
class Cat extends Animal{
@Override
public void bark() {
System.out.println("喵喵.....");
}
}
public class Test {
//向上转型
public static void func(Animal a){
a.bark();
}
public static void main(String[] args) {
//多态的应用
func(new Dog());
func(new Cat());
}
}
输出结果:
汪汪…
喵喵…
总结:
1.抽象类最大的意义,是为了继承
2.为了继承,抽象方法不能被static,private,final修饰
3.不能实例化抽象类
二.接口
1.接口的概念和定义
在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型,它的结构与抽象类非常相似,具有数据成员、抽象方法、默认方法和静态方法,但它与抽象类有下列不同。
(1)接口的数据成员都是静态的且必须初始化,即数据成员必须是静态常量。
(2)接口中除了声明抽象方法外,还可以定义静态方法和默认方法。
定义:
2.接口特性
1.接口类型是一种引用类型,不能直接new接口对象
interface IFlying{
void Flying();
}
public class Test1 {
public static void main(String[] args) {
//Error:IFlying是抽象的; 无法实例化
IFlying b = new IFlying();
}
}
2.接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)
interface IFlying{
// Error: 此处不允许使用修饰符protected
protected void Flying();
}
3.接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
interface IFlying{
// Error: 接口抽象方法不能带有主体
void Flying(){
System.out.println("在天上飞");
}
}
4.重写接口中方法时,不能使用default访问权限修饰
interface IFlying{
void Flying();
}
class Duck implements IFlying{
//Error:正在尝试分配更低的访问权限; 以前为public
@Override
void Flying() {
System.out.println("天上飞");
}
}
5.接口中可以含有变量,但是接口中的变量会被隐式的指定为public static final 变量
interface IFlying{
void Flying();
String name = "大飞";//默认 public static final 修饰
}
- 接口中不能有静态代码块和构造方法
interface IFlying{
void Flying();
//编译失败
public IFlying(){
}
}
7.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
7. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
8. jdk8中:接口中还可以包含default方法。
实现案列:
interface ISwimming{
void swimming();
}
interface IRuning{
void runing();
}
class Duck implements ISwimming,IRuning{
public String name;
public Duck(String name) {
this.name = name;
}
@Override
public void swimming() {
System.out.println(this.name+"水里游");
}
@Override
public void runing() {
System.out.println(this.name+"地上跑");
}
}
class Dog implements IRuning{
public String name;
public Dog(String name) {
this.name = name;
}
@Override
public void runing() {
System.out.println(this.name+"水里游");
}
}
public class Test1 {
public static void func1(IRuning r){
r.runing();
}
public static void func2(ISwimming s){
s.swimming();
}
public static void main(String[] args) {
func1(new Dog("大飞"));
func1(new Duck("白糖"));
func2(new Duck("白糖"));
}
}
输出结果
大飞水里游
白糖地上跑
白糖水里游
总结:
1.接口不能被实例化
2.当中的成员方法不能有具体的实现 ①抽象方法:默认是public static 的方法 ②JDK1.8开始,允许有可以实现的方法,只能有default修饰 ③可以实现一个静态的成员方法
3.成员变量默认是public static final 来修饰
4.子类重写抽象方法,必须加上public
5.接口中不能有静态方法和构造方法