上一篇呢说过了类的继承,今天咱们来说一下抽象类,什么事抽象类呢?
那就是抽象的类呗,什么是抽象? 笼统,模糊,看不清的,看不明白就是抽象,抽象类就是本身不断向上抽取而来,在抽取的过程当中,子类的方法方法声明相同,方法体不同,在抽取的过程中,形成了没有方法体的方法,那这个方法就称之为抽象方法,抽象方法所在的类就是抽象类。
描述一个事物时,没有足够的信息对该事物进行具体的描述,这个类就是抽象类。
举个栗子:
狗–行为–吼叫 ===>旺旺的
狼–行为–吼叫 ===>嗷嗷的
对上边的栗子进行代码上的说明:
abstract class 犬科{
abstract void 吼叫();
}
class 狗 extends 犬科{
void 吼叫(){
syso("汪汪汪");
}
}
class 狼 extends 犬科{
void 吼叫{
syso("嗷嗷嗷");
}
}
抽象类只是描述事物应该具备的行为,具体他具体的内容,要根据子类的特点来决定。
抽象类具备的特点:
1.没有方法体的方法是抽象方法,一定定义在抽象类当中。
2.抽象类和抽象方法必须用关键字abstract所修饰abstract只能修饰类和方法。
3.抽象类不能被实例化,意味着不能创建对象。原因:逆向思维:如果一个抽像类可以被实例化,那就代表它有对象,那就可以调用类中的成员方法,
但是抽象方法只能声明没有方法体,调用没意义,所以不能被实例化,简而言之:抽象方法调用没意义,
4.抽象类必须由其子类覆盖所有的抽象方法后,其子类才能实例化,否则其子类还是一个抽象类。
细节问题?
1.抽象类一定是父类么?
是的,因为抽象类没有足够的信息去描述一个事物,他要依托子类信息具体化。
2.抽象类中是否有构造函数呢?
有,一个类的构造函数除了给自己创建对象,还要给子类对象初始化。
3.抽象类中是否可以不定义抽象方法呢?
可以。存在的目的:不让这个类创建对象,这个在java体系当中非常常见。
4.抽象关键字不能和那些关键字共存?
(1)final:原因:final修饰类意味着这个类不能被继承,
而abstract修饰类意味着这个类必须有子类,这是矛盾的。
(2)static 原因:静态的,意味着可以直接用类来调用,而抽象方法直接用类调用没有意义。
(3)private原因:私有的,意味着本类之外其他类不能调用,而抽象方法不能实现的就要依靠其他类来实现。
抽象类和一般类的比较?
相同之处:
都是用来描述事物的,都可以定义属性,行为和构造函数。
不同之处:
1.一般类当中不可以定义抽象方法,而抽象类可以。
2.一般类可以被实例化,而抽象类不能。
3.一般类可以被继承可以不被继承,而抽象类一定要被继承,需要其子类覆盖所有的抽象方法后,子类才能被实例化。
说晚了类,再来说一下接口吧。interface,可能有人会问,怎么说这类就说到接口了呢,类和接口呢肯定是有关系的,当抽象类中所有的方法都是抽象方法时,我们就可以把这个抽象类定义为接口了。
初期理解:可以把接口理解为一种特殊的抽象类。意味着接口当中所有的方法都是抽象方法。
接口固定的格式如下:
interface 接口名{
接口内容
}
接口的特点:
1.接口用interface来定义。
2.接口中的成员都有固定的修饰符。
3.接口不能被实例化。
4.接口必须是由其子类覆盖所有的抽象方法后,其子类才能被实例化,否则该子类还是一个抽象类。
5.接口当中的成员都是public修饰的。
大概了解了接口之后,来认识一下接口的成员变量吧。
接口当中的成员:
常见的
1.常量 //有几个固定的修饰符:public static final
2.抽象方法 //也有固定的修饰符: public abstract
接口是需要被实现的,通过关键字:implements
同样实现接口的类的命名:InterImpl
抽象类当中定义的默认和接口当中定义的默认是不一样的。
类和类之间的关系是继承,类和接口之间的关系是实现。
接口的好处:
接口可以被多实现,这个是java改良了多继承的机制的结果。
* 误区:*
接口当中定义的方法是符合基本方法定义格式的,要明确结果和未知的内容。只不过函数内容由其子类来体现。
【抽象接口当中的成员:类和接口的区别】
一个类只能继承一个父类,但是可以有多个接口。
接口的出现是避免的单继承的局限性。
类与类之间的关系,是继承,而且是单继承
类与接口之间的关系,是实现,而且是多实现
接口与接口之间的关系,是继承,而且是多继承。
接口的应用
1.接口的出现降低了耦合性
2.接口的出现提高了拓展性
3.接口就是对外暴露的规则
接口的广义理解:凡是对外暴露的,我们都可以称之为接口。
抽象类和接口之间的区别:
1.抽象类是用来继承的,只能单继承。
接口是用来实现的,可以多实现。
2.抽象类当中可以提供非抽象的内容,直接提供给子类使用。接口只能定义抽象方法,需要子类全部实现。
3.抽象类存在着继承关系,是is a的关系
接口存在着实现关系,是like a的关系。
相同点:
他们都是不断向上抽取获得到的。
定义在抽象类中的一般都是基本功能,而接口中定义的方法一般都是额外功能。
下面用代码简单说一下:
interface 生物
{
void eat();
void drink();
void sleep();
void shock();
void.......
}
abstract class 动物 implements 生物
{
void eat(){}
void drink(){}
void sleep(){}
void shock(){}
......
}
class Dog extends 动物
{
void eat(){}
}
class Cat extends 动物
{
void sleep(){}
}
子类在直接实现接口的时候,需要覆盖接口当中的所有方法,但是子类就像对一个方法进行具体化的指定,
定义一个抽象类,让他实现指定接口,并且实现接口中的所有方法,然后子类在继承这个抽象类,就可以想
重写哪个方法就重写哪个方法。
没有抽象方法的抽象类,可以方便的创建接口的对象覆盖指定的功能。
java 面向对象的三个特征已经说过了封装和继承、最后咱们来说一下多态。
多态:就是多种形态
java包含两种多态:
静态多态: 函数的重载
动态多态: 对象的多态性。
多态在程序中的体现:
//程序当中体现多态:
Dog d = new Dog();
Animal a = new Dog();
//前提:狗和动物的关系,狗属于动物一种,所以狗是继承于动物的。
多态在程序当中的体现,父类或者接口的引用,指向了子类的对象时,这就是多态。
多态:多种形态
* 好处:提高了代码的扩展性
* 弊端:前期建立了父类的引用,虽然能够接受所有的子类的对象,但是只能使用父类当中的功能,不能使用子类特有的功能。因为前期程序不知道后期新添的内容,但是前期的程序可以使用子类覆盖了父类方法的内容。
多态的前提:
1.必须存在继承关系
2.通常存在着覆盖的操作
今天就说这些吧,简单地了解一下,以后经常使用就会熟练理解了。
最后咱们还是用一个demo说一下抽象和多态吧
抽象
/*描述犬类
* 犬类: 导盲犬,牧羊犬,搜爆犬,宠物犬
*
* 定义在抽象类中的一般都是基本功能,而接口中定义的方法一般都是额外功能。
* */
public class InterTest {
public static void main(String[] args) {
ExplosiveDog dog = new ExplosiveDog();
dog.explosive();
dog.shock();
}
}
abstract class Dog{
abstract void shock();
}
interface Explosivable{
abstract void explosive();
}
class ExplosiveDog extends Dog implements Explosivable{
@Override
void shock() {
System.out.println("声嘶力竭的汪汪汪");
}
@Override
public void explosive() {
System.out.println("搜爆搜爆!!!");
}
}
下面说一下多态:
先写一个动物的抽象类:
public abstract class Animal {
abstract void eat();
abstract void sleep();
void run(){
System.out.println("动物都能跑");
}
}
在写一个猪类:
public class Pig extends Animal{
@Override
void eat() {
System.out.println("猪吃饲料");
}
@Override
void sleep() {
System.out.println("猪睡猪圈");
}
void gongdi(){
System.out.println("猪会拱地!!");
}
}
接着我们写一个狗类和猫类:
public class Dog extends Animal{
@Override
void eat() {
System.out.println("狗吃狗粮");
}
@Override
void sleep() {
System.out.println("狗睡在狗窝");
}
@Override
void run() {
System.out.println("狗跑的飞快!!");
}
public void lookHome(){
System.out.println("看家护院");
}
}
猫类:
public class Cat extends Animal{
@Override
void eat() {
System.out.println("猫吃鱼");
}
@Override
void sleep() {
System.out.println("猫睡在床上");
}
public void catchMouch(){
System.out.println("抓老鼠");
}
}
最后写一个测试用的类:
public class DuotaiDemo {
public static void main(String[] args) {
Cat c1 = new Cat();
c1.eat();
c1.sleep();
c1.catchMouch();
Dog d1 = new Dog();
d1.sleep();
d1.eat();
Animal a1 = new Cat();
animalEatSleep(a1);
System.out.println("----------");
Animal a2 = new Dog();
animalEatSleep(a2);
System.out.println("----------");
Animal a3 = new Pig();
animalEatSleep(a3);
}
public static void dogEatMethod(Dog d){
d.eat();
d.sleep();
}
public static void animalEatSleep(Animal a){
a.eat();
a.sleep();
a.run();
}
}
相信经过今天的学习,最后这个demo也就比较容易懂了,今天就到 这里吧。晚安^_^