1.抽象类
1.1第一眼看抽象类
当我们第一眼见到这个抽象类名字的时候,我相信大家已经有了抽象类与普通类的一些感性认识,
抽象类顾名思义就是类的进一步抽象,我们第一次见到应该有了这样的认识.所谓抽象就是忽略事物的细节,关注事物的主体部分,同样的抽象与普通的类也有这样的关系. 那么让我们进一步的来了解抽象类吧.
1.2抽象的的概念
1.2.1 一个例子:
首先我们先举一个例子:当我们要实现一个程序来完成各种图形的绘制的时候,比如说正方形,矩形,圆形等等.按照我们之前没学过抽象类的时候,我们首先可以想到的是先定义一个图形的父类,并且这其中还有面积,周长等变量.然后再定义以个绘制图形的方法,.但是方法体好像写什么都不合适,方法中就是空语句,然后再去创建各个具体图形的子类并且去继承图形父类,并且重写父类中绘图的方法,然后使用多态机制,让父类型引用指向子类型对象,最后调用方法.这样当然是可行的.但是细想还是会有一些问题存在
如果你不小心创建了父类的对象好像是什么用都没有,因为你没有具体的图形,里面的面积和周长,图形绘制都是没有必要的,进行相关操作是没有意义的,反而还会容易发生错误.
这时候就可以使用抽象类就再合适不过了
public class Test {
public static void main(String[] args) {
Graph squ=new Square();
squ.Draw();
Graph cir=new Circle();
cir.Draw();
}
}
// 图形类
abstract class Graph{
public double s; // 面积
public double c; // 周长
public abstract double GetS(); // 计算面积
public abstract double GetC(); // 计算周长
public abstract void Draw(); //绘制图形
}
// 正方形类
class Square extends Graph{
double a; // 边长
@Override
public double GetS() {
return a*a;
}
@Override
public double GetC() {
return 4*a;
}
@Override
public void Draw() {
System.out.println("正方形");
}
}
// 圆形类
class Circle extends Graph{
double r; // 半径
final static double PI=3.1415926;
@Override
public double GetS() {
return PI*r*r;
}
@Override
public double GetC() {
return 2*PI*r;
}
@Override
public void Draw() {
System.out.println("圆形");
}
}
以上代码是图形类的具体实现,看到这儿大家应该看到抽象类的作用了,和一些使用场景.
1.2.2 抽象类的概念
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
以上Graph就是抽象类,抽象类使用abstract修饰,但是抽象类是可以包含具体的行为和状态的
所以说抽象类是半抽象的,后面接口是完全抽象的.
1.3抽象类的特征
1.3.1
抽象类是不支持实例化的,也就是不能通过new关键字创建对象,抽象类就是被子类继承的.
抽象类中既可以有抽象方法,又可以有普通方法,和普通变量以及实例变量,所以前面才说抽象类并不是完全抽象的,抽象类是半抽象的.
抽象方法是没有方法体的方法,也就是没有实现的方法,抽象方法需要用abstract修饰
1.3.2 与abstract 类的非法的修饰符组合
private
我们已经知道,抽象类就是为了被继承,但是private修饰的并不支持继承,自然抽象类中也不能有private修饰了
final
final修饰的类不支持继承,所以也不能与抽象类中abstract在一起使用
static
抽象方法不能用static修饰,static修饰的方法是类级别的方法,不是对象级别的方法.而抽象类使用来被继承的.
1.3.3 抽象类中需要注意的几点
1.抽象方法可以不出现在抽象类中,但是抽象方法一定是只能在抽象类中存在的(接口也是一种完全抽象的类)
2.抽象类中可以有构造方法,是创建子类对象,供给父类中的成员变量初始化的
1.3.4 抽象类的作用
抽象类的出现给了编译器多了一层编译时期的校验,以减少出错的概率,这样是很有意义的,就像前面
如果创建了普通类,就有可能出错,从而无法达到我们的需求和功能,这是很有必要的.
2.接口
2.1接口的概念:
提到接口我们日常生活中到处可见,比如所USB接口,充电器接口,电视机接口,集成电路上的各种接口.
接口:多个类的公共规范,是一种引用数据类型,接口是完全抽象的,接口中所有的变量都是常量,所有的方法都是抽象方法,但是在java8后接口中可以存在默认的有方法体的方法
2.2接口的特征
2.2.1
定义接口使用interface关键字
接口中的方法都是抽象方法(默认方法除外),变量都是常量,并且访问权限都是public,所以我们在定义接口中的变量和抽象方法的时候public static final和public abstract可以省略不写,可以看到上面代码中对应的都变成灰色了.
2.2.2 接口支持多继承
可以清楚的看到一个接口可以同时继承多个接口,这也叫做接口的合并,接口的多继承,和好的解决了
类的单继承的缺陷
2.2.3接口的使用
由于接口是完全抽象的,所以接口也是不能直接new 对象,那我们就自然想到了用一个普通类去继承一个接口,事实上也是很类似的,如果一个类想去使用一个接口,那么这个类就要去实现这个接口中所有的抽象方法,而类去继承接口,在这里有一个新的叫法:叫做类实现接口,并且使用关键字implements来代替之前继承的关键字extends.
并且一个类可以实现多个接口,也要重写这些接口中的抽象方法
同样的道理如果一个类没有实现接口中的抽象方法,那么这个类也一定是抽象类
到最后普通类继承这个抽象类的时候还是要重写这些抽象方法
当然如果不重写抽象方法的话,那D类也必须是抽象类
implements和extends同时存在
要注意这两个关键字的使用顺序,先extends后implements
2.2.4面向接口编程
前面的抽象类可以面向抽象编程,就是抽象类引用指向之类的对象,也是充分利用多态机制
而这里的面向接口编程,则可以让我们忘记类型直接使用接口类型去引用被他实现的的类
这样就看不到类型了
public class Test {
public static void main(String[] args) {
Animal a=new Dog("小狗",8);
test(a);
test2(new Dog("二哈",5));
test3(new Dog("1",1));
}
public static void test(Animal a){
a.eat();
}
public static void test2(IRunning r){
r.run();
}
public static void test3(ISwing s){
s.swig();
}
public static void test4(IFlying f){
f.fly();
}
}
abstract class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void eat();
}
interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwing {
void swig();
}
class Dog extends Animal implements IFlying,ISwing,IRunning{
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(name+"狗吃骨头");
}
@Override
public void fly() {
System.out.println(name+"狗飞快的跑");
}
@Override
public void run() {
System.out.println(name+"正在狗腿跑");
}
@Override
public void swig() {
System.out.println(name+"狗游泳");
}
}
可以看到上面方法中的形参列表可有抽象类,接口.
在传参的时候如果该类继承或者实现了该接口,就会发生向上类型转换,这样整个程序的适配性就很会强了,只要是继承了该抽象类或是实现了这个接口都可以作为参数传递,大大提高了程序的扩展力,
降低了程序的耦合度.这就是面向接口编程和面向接口编程.
3.总结抽象类与接口
首先抽象类是半抽象的,接口是完全抽象的,这也决定了他们的不同
1.一个类可以实现(implements)多个接口,但是一个普通类只能继承(extends)一个抽象类
2.抽象类中可以存在普通方法和普通变量,而在接口中只存在常量和抽象方法
3.抽象类中可以有不同与public 的访问修饰符,而接口中的访问修饰符只能是public(默认方法除外)
4.抽象类可以实现若干接口,接口可以继承多个接口,但是接口不能继承抽象类
以上就是本次的全部内容,谢谢大家的观看