这篇文章主要介绍Java中抽象类与普通类的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
在面向对象概念中,所有的对象都是通过类来描述的,但是反过来,并不是所有的类都是用来描述对象的.如果一个类中没有足够多的信息来描述一个具体的对象,这样的类就是抽象类。
看到这里可能还是觉得有些难以理解,举个例子说明一下:说到动物你会想到什么?猫,狗,鸡鸭鹅?当然这些都可以.那么动物这两个字,你能确定一个具体的对象吗?显然不能.甚至更严格意义上讲,说到猫你会想到什么?橘猫,短美…
毕竟:
一千个人心中有一千个哈姆雷喵.
所以我们在设计中,动物类可以设计成为抽象类,而某一种特定的物种可以采用通过继承动物类实现.
多态这部分我理解了好久,有一天突然就会用了,也明白所谓的父类引用指向子类对象是什么意思了.但是写完前面发现,自己明白了讲出来还是很模糊.多态真的是很重要很重要的一个点,要好好体会这部分.
抽象类的语法规则
抽象类的语法规则:abstract
关键字修饰
1.抽象类不可以被实例化.
2.抽象类不定有抽象方法.
3.一个类中如果有抽象方法,那么这个类一定是抽象类.
4.抽象类中可以存在普通属性、方法、静态属性和静态方法.
5.抽象类中可以存在构造方法.
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 注解.就不继续修改了.
1.不实现抽象类中的抽象方法
当不对抽象类中的抽象方法进行重写的时候,子类一定也是抽象类.(有抽象方法的类一定是抽象类)
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(){}; }
2.实现抽象类中的抽象方法
当对抽象类中的所有抽象方法进行实现之后,现在的猫咪类可以是一个普通类了.
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 + "在懒洋洋的跑"); } }
小结
1.普通类可以实例化调用,但是抽象类不可以,因为抽象类只是一种概念,无法映射为具体的对象.
2.普通类和抽象类都可以被继承,但是抽象类被继承之后,子类需要重写抽象类中的全部抽象方法,否则子类必须是一个抽象类.
以上是“Java中抽象类与普通类的区别有哪些”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。