前言
我们在上课时,一看到课本里有抽象两个字就感觉难了,为什么?
还记得高中数学的抽象函数吗?我在坐标轴上随便画一条线,我也不知道这条线具体函数是什么,但是我既然画得出,那就绝对有一个函数对得上它。我先把它设为【y = f(x)】,具体是什么后面慢慢求。这就叫抽象函数。我高中时就被这个东西搞得我对抽象两个字有阴影,连大学时学java,老师说抽象我都睡觉了……
抽象是什么意思?比如说,我们都是外星人,现在刚刚来到地球,我们现在所看到的【人、猴子;鱼、老虎;菩提树、人参果;细胞甚至是病毒】,对于身份为外星人的我们来说,我不明白这些究竟是些什么东西。我们只知道这些都是地球上的生物,蛋疼的是我们根本不知道这具体是什么。
这个例子用抽象来讲,这些个体都是一个具体的类:
“人类” 和 “猴子类” 可以用【高智商动物类】来做为他们的父类,
“鱼类” 和 “老虎类” 可以用【一般动物类】做为父类,
这两个【高智商动物类】和【一般动物类】又可以用{动物类}做为父类;
“菩提树类” 和 "人参果类" 可以用{植物类}做为父类,
“细胞类” 可以用{单细胞生物类}做为父类,
这个{动物类}、{植物类}、{单细胞生物类}还可以用{【生物类】}做为父类;
“病毒类” 可以用{【非生物类】}做为父类;
这两个{【生物类】}{【非生物类】}还可以用{【(地球类)】}做为父类
大家看,越往父类上面跑,我们就越不知道这是个什么东西,这就叫抽象。甚至最后只知道这个东西属于宇宙,却不知道这是【银河系的太阳系的地球的生物类的人】。懂抽象了吧?
Java中的抽象
基本类 && 基本方法
我们都知道,我们学习时一般写的类和方法是这样的:
public class Animal{
public void shouts(){
System.out.println("动物在叫");
}
}
这个时候有一只狗和一只猫跑过来叫,那两种不同的物种的叫声是不一样的吧?现在你说:我再写两个class,放入shouts方法不就好了嘛?这当然可以。但是你在说这句话时想过吗?全世界有多少个动物?这些动物只会叫吗?按照这样每种动物的每种方法都罗列出来,这要多大的工程?
我们通过现实生活不难发现,动物都会叫,对吧?只是叫声不一样而已。
抽象类 && 抽象方法
抽象类的公有抽象方法
好的,按照前言里面的说法,这有只动物,我现在也不知道是什么动物,那我就创建一个抽象的动物类;每只动物都会叫对吧,我就把叫这个方法定义为抽象方法,我也不知道这个动物怎么个叫法,它爱怎么叫怎么叫,我只要知道它会叫就可以了;它还会走是吧,行(关键词:abstract):
abstract class Animal{
public abstract void shouts();//叫法(抽象方法)
public abstract void onTheWay();//赶路法(抽象方法)
}
子类的实现父类公有方法
现在我抓起一个动物,我不知道这是什么动物,我只知道它走路不发出声音,喵喵叫(我现在还不知道它叫猫啊),好的,那就把它定义为A动物呗,它属于动物类的,叫声喵喵喵,走路不发出声音,好办
class A extends Animal{//创建一个 A 类,继承动物类
@Override
public void shouts() {//实现动物类的方法一:叫声
System.out.println("喵~喵~");
}
@Override
public void onTheWay() {//实现动物类的方法二:走路
System.out.println("不发出声音地走");
}
}
我又抓起一只动物B,但它是用游的,而且叫得很悲伤,那也行
class B extends Animal{//再创建一个 B 类继承动物类
@Override
public void shouts() {//实现动物类的方法一:叫声
System.out.println("悲伤的叫声");
}
@Override
public void onTheWay() {//实现动物类的方法二:走路
System.out.println("游着走");
}
}
多个子类中与众不同的私有方法
注意:
此处的私有方法是指其他的动物所没有的方法,但是我们仍然可以看的到的,所以必须是public。
你可不能是private啊,那相当于是动物的血液在流,你看不到的啊,
这个private 想看只能跑到动物的血管里去看......
现在我右手的A动物又给我展示了一个新技能:抓老鼠,得意地看着B:“哼,你不会吧<_<”;
B不甘示弱,也告诉了我什么叫作“鲸落”,也傲慢地看着A:“哼,你会吗>_>”
噢,原来他们两个都各有千秋呀:
class A extends Animal{
@Override
public void shouts() {
System.out.println("喵~喵~");
}
@Override
public void onTheWay() {
System.out.println("不发出声音地走");
}
public void catchMouse(){//具体类的私有方法
System.out.println("我会抓老鼠,你会吗<_<");
}
}
class B extends Animal{
@Override
public void shouts() {
System.out.println("悲伤的叫声");
}
@Override
public void onTheWay() {
System.out.println("游着走");
}
public void whaleFalls(){//具体类的私有方法
System.out.println("我有鲸落,你有吗>_>");
}
}
多态
过了两三天,我随手抓起一只:“你,对,就你,给我叫声听听”,我们听听它怎么叫的:
public class Test {
public static void main(String[] args) {
Animal animal = new A();//我随手抓起的动物(Animal animal),我也只知道它是一只动物,但它确确实实是两个种类中的A种类的(new A())
animal.shouts();//让它叫一声
}
}
"E:\Program Files\Java\jdk-12.0.2\bin\java.exe" "-javaagent:E:\ideaIU-2019.3.3\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=53660:E:\ideaIU-2019.3.3\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "E:\eclipse\HomeWorks\0729\out\production\0729;E:\Program Files\Java\jar\junit-4.11.jar" Test.Test
喵~喵~
Process finished with exit code 0
但是这时我说:“你给我抓只老鼠看看”animal.catchMouse();
,这时这只动物就懵圈了:你怎么这么确定我会抓老鼠?你只知道我是动物,你又不知道我是猫……
???这是怎么回事呢?
多态,打个比方,有一只动物跑到我家来。
(1) 孩子问我:“粑粑,这个是什么动物呀?它会不会叫?【父类抽象类 + 抽象方法】”(public abstract class Animal{ public abstract void shout(); }
)
(2) 我回答孩子:“这叫猫,它会喵喵叫~【子类继承父类 + 重写父类的抽象方法】”(public abstract class Cat extends Animal{ @Override public void shout(){...} }
)
(3) 孩子:“那我们让它叫一声看看好吗?【创建一个动物对象,目前这只动物是猫类,但孩子不知道,但它确确实实是猫类的】”(Animal animal = new Cat(); animal.shout();
)
(4) 孩子:“粑粑,那猫除了会叫,它还会干什么呀?【创建一个猫对象,因为孩子知道这是一只猫了,她想知道猫还会干什么,于是就一直盯着那只猫看】”(Cat cat = new Cat();
)
(5) 过了一会儿,孩子开心地说:“粑粑,我知道啦,猫还会抓老鼠 ^_^ 【访问这个猫类,得到抓老鼠的方法】”(cat.catchMouse();
)
这个例子中,
(1)第三步,创建一个【抽象类的实现类的对象】,以抽象类来接收它,
这种 **创建子类对象,用其父类来接收** 的方法就叫多态;
(2)第四步,当我们使用多态时(在使用父类接收子类对象时),
我们是访问不了该子类的其他方法的,只能访问它公共的抽象方法,
就像上面这个例子中,我们只知道这只动物会叫,会走,但不知道它会抓老鼠。
要想访问的话,我们得创建具体类的实例对象,也就是 Cat cat = new Cat();
这时我们才能访问到 cat.catchMouse();
亲爱的朋友,你学会了吗?
后言
由于本文是有关于抽象的知识,本编文章是以虚拟现实的想法完成的,不一定适合所有朋友。如果有什么疑问欢迎留言,我会以最大的努力为您解答,共同努力,共同进步!
非常感谢您的耐心观看!!您的理解和收获是我的最大动力。再次衷心感谢!!!