发布于2021-06-14 10:48 阅读(599) 评论(0) 点赞(22) 收藏(5)
其实这篇文章已经在写了,在写的过程中也看了许多人整理的优秀的文章,不禁想到,他们整理的那么好,那么详细,我在这里重复的做这些事情真的有意义吗?看了之前几篇文章的读者在下方的评论之后,不禁觉得,可能这就是意义吧!
从刚接触Java的无所适从,到现在逐渐能够看懂并理解一部分内容.这中间的变化,也是一点一点积攒而成的.
现在每天将自己已经学习过的知识整理成笔记,养成写博客的好习惯.学而时习,之不亦乐乎?
我也是在不断学习的过程中,文章中的问题理解不到位的地方甚至出现的错误,欢迎大家指出,我会及时订正.
每个问题都会进行小结,中间可能会对问题进行一些扩展,如果想看结论可以直接跳转到小结部分.
在面向对象概念中,所有的对象都是通过类来描述的,但是反过来,并不是所有的类都是用来描述对象的.如果一个类中没有足够多的信息来描述一个具体的对象,这样的类就是抽象类。
看到这里可能还是觉得有些难以理解,举个例子说明一下:说到动物你会想到什么?猫,狗,鸡鸭鹅?当然这些都可以.那么动物这两个字,你能确定一个具体的对象吗?显然不能.甚至更严格意义上讲,说到猫你会想到什么?橘猫,短美…
毕竟:
一千个人心中有一千个哈姆雷喵.
所以我们在设计中,动物类可以设计成为抽象类,而某一种特定的物种可以采用通过继承动物类实现.
多态这部分我理解了好久,有一天突然就会用了,也明白所谓的父类引用指向子类对象是什么意思了.但是写完前面发现,自己明白了讲出来还是很模糊.多态真的是很重要很重要的一个点,要好好体会这部分.
抽象类的语法规则:abstract
关键字修饰
public abstract class AbstractObject{
// 普通属性
String name;
// 构造方法
public AbstractObject(String name) {
this.name = name;
}
// 静态方法 - 类名访问
public static void staticMethod(){
System.out.println("抽象类可以有静态方法.");
}
// 抽象方法
public abstract void move();
// 普通方法
public void commonMethod(String food){
System.out.println("抽象类可以有普通方法.");
}
}
这部分可以直接暂时记住结论,整个过程可以暂时先跳过后面补,按照我的学习经历(基础差到爆),这部分直接看会很懵.
定义一个动物的抽象类,动物总得动吧(并不!)所以定义一个共性的move()方法.
public abstract class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public abstract void move();
}
当我使用IDEA写示例的时候直接出现了第二种情况!见鬼了抽象类new
出来了!
public class Test {
public static void main(String[] args) {
// 抽象类不能实例化!会直接报编译期错误!
//标红信息: 'Animal' is abstract; cannot be instantiated
Animal animal = new Animal("小猫");
// 第二种情况
Animal animalObjcet = new Animal("小猫") {
@Override
public void move() {
System.out.println("我开始移动了!");
}
};
}
}
这里涉及到了一个知识点叫做匿名内部类.
匿名内部类的格式如下:
new 类名或者接口名(){
重写方法;
}
// 放到一起对比看,很明显后面的是一个匿名内部类
new Animal("小猫") {
@Override
public void move() {
System.out.println("我开始移动了!");
}
};
匿名:这个类没有名字
内部类:存在于某个类的内部的类.
它实际上是继承并实现了Animal抽象类的一个子类.也就是说这里并不是实例化出了Animal类,这个简便的写法相当于我们进行了如下的写法.
public class AnimalObject extends Animal{
public AnimalObject(String name) {
super(name);
}
@Override
public void move() {
System.out.println("我是一只能动的动物!");
}
}
public class Test {
public static void main(String[] args) {
AnimalObject animalObject = new AnimalObject("我是动物抽象类的子类");
animalObjcet.move(); // 我是一只能动的动物!
}
}
注意:这里有一个需要强调的地方,对于抽象类中的方法我们的用词应该是实现.对于已经实现了的方法,我们的用词才可以是重写.写到后面发现了前面描述过程中我用词都是重写这里进行了修正.
错误写法:不重写(Override)抽象类中的抽象方法
正确写法:不实现(Implement)抽象类中的抽象方法
再次补充:好像说成重写也不能算错误,IDEA自动生成的里面也加了 @Override 注解.就不继续修改了.
public abstract class AbstractCat extends Animal{
Integer weight;
public AbstractCat(String name, Integer weight) {
super(name); // 继承父类的名称
this.weight = weight; // 猫咪的年龄
}
// 这个是没有重写,依旧是了抽象方法
public abstract void move();
// 注意:下面这种写法是重写过之后的!只是方法体为空.
// public void move(){};
}
public class Cat extends AbstractCat{
public Cat(String name, Integer weight) {
super(name, weight);
}
@Override
public void move() {
System.out.println("一只奔跑的重达" + weight + "kg的" + name);
}
}
测试一下:
public class Test {
public static void main(String[] args) {
Cat cat = new Cat("橘猫", 20);
cat.move(); // 一只奔跑的重达20kg的橘猫
}
}
好了到这里,属于你的橘猫终于跑起来了!
我看很多文章都说要子类要重写(重写是错误的!这里更正为实现)父类的抽象方法,抽象方法.那我如果只实现部分抽象方法呢?
第一步:改造Animal类
public abstract class Animal {
String name;
public Animal(String name) {
System.out.println("我是动物的构造方法!");
this.name = name;
}
// 多添加几个抽象方法
public abstract void move();
public abstract void eat();
public abstract void sleep();
}
第二步:AbstractCat 类中实现部分抽象方法
// 不添加 abstract 关键字会报错
// Class 'AbstractCat' must either be declared abstract or implement abstract method 'move()' in 'Animal'
public abstract class AbstractCat extends Animal{
Integer weight;
public AbstractCat(String name, Integer weight) {
super(name);
System.out.println("我是抽象猫咪的构造方法!");
// 继承父类的名称
this.weight = weight; // 猫咪的年龄
}
@Override
public void eat() {
System.out.println(this.name + "在吃猫粮");
}
@Override
public void sleep() {
System.out.println(this.name + "睡觉了!");
}
}
第三步:Cat类登场
public class Cat extends AbstractCat{
public Cat(String name, Integer weight) {
super(name, weight);
}
/*
sleep方法和eat方法已经在父类中实现过了,所以这里只剩下最后一个 move 是需要实现的抽象方法.
*/
@Override
public void move() {
System.out.println("重达" + weight + "kg的" + this.name + "在懒洋洋的跑");
}
}
这篇博客的引用部分关于为什么使用抽象类写的很好!
Java基础系列第一弹之方法重载和方法重写的区别
Java基础系列第二弹之Java多态成员访问的特点
Java基础系列第三弹之操作字符串的类都有哪些?区别是什么?
原文链接:https://blog.csdn.net/Lf_MrF/article/details/117686603
作者:想要飞翔的天使
链接:http://www.javaheidong.com/blog/article/222767/8e460cd2c29859b69d14/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!