1.抽象类
普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类是指在普通类的结构里面增加抽象方法的组成部分。
那么什么叫抽象方法呢?在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。而抽象方法,是指只有方法声明没有方法实现的方法,同时抽象方法还必须使用关键字abstract做修饰。
而拥有抽象方法的类就是抽象类,抽象类是抽象方法与非抽象方法的集合,抽象类要使用abstract关键字声明。
2.语法格式
【修饰符】abstract class 类名{
}
3.抽象类使用注意
1.抽象类无法实例化,抽象类是专门给子类继承的
public abstract class A {
public A(){
}
}
class text{
public static void main(String[] args) {
new A();//Error:(5, 9) java: 集成开发.抽象类.A是抽象的; 无法实例化
}
}
2.final与abstract无法联合使用
原因:final修饰的类与方法不能被继承和修改,但是抽象类是专门给子类继承的,抽象方法还必须实例化
public final abstract class A {//Error:(3, 23) java: 非法的修饰符组合: abstract和final
public A(){
}
}
3.抽象类虽然无法被实例化,但是抽象类有构造方法,因为抽象类有自己的一些属性。这个构造方法是给子类使用的
public abstract class A {
String name;
public A(){
}
}
class B extends A{
private String name;
public B(String name){
super();
this.name=name;
}
}
class text{
public static void main(String[] args) {
B b=new B("张三丰");
}
}
4.如果子类无法实例化父类全部的抽象方法,则该子类只能定义为一个抽象父类的抽象子类
原因:子类继承抽象父类,那么势必将父类的抽象方法继承过来,但是抽象方法只能在抽象类中,此时要么把子类定义为抽象类,要么将继承过来的抽象方法全部实例化
public abstract class A {
public abstract void some();
public abstract int move();
}
class B extends A{//Error:(7, 1) java: 集成开发.抽象类.B不是抽象的, 并且未覆盖集成开发.抽象类.A中的抽象方法move()
public void some(){
}
//move方法没有声明
public static void main(String[] args) {
}
}
5.抽象类中可以没有抽象方法,但是抽象方法必须在抽象类中
public abstract class A {
public int move(){
return 123;
}
}
class B{//B含有抽象方法,但是B不是一个抽象类
public abstract void some();
public static void main(String[] args) {
}
}
4.抽象类实例
例如,现在有三类事物:
(1)机器人:充电,工作;
(2)人:吃饭,工作,睡觉;
(3)猪:进食,睡觉。
现要求实现一个程序,可以实现三种不同事物的行为。
先定义一个抽象行为类:
package com.wz.abstractdemo;
public abstract class Action{
public static final int EAT = 1 ;
public static final int SLEEP = 3 ;
public static final int WORK = 5 ;
public abstract void eat();
public abstract void sleep();
public abstract void work();
public void commond(int flags){
switch(flags){
case EAT:
this.eat();
break;
case SLEEP:
this.sleep();
break;
case WORK:
this.work();
break;
case EAT + SLEEP:
this.eat();
this.sleep();
break;
case SLEEP + WORK:
this.sleep();
this.work();
break;
default:
break;
}
}
}
定义一个机器人的类:
package com.wz.abstractdemo;
public class Robot extends Action{
@Override
public void eat() {
System.out.println("机器人充电");
}
@Override
public void sleep() {
}
@Override
public void work() {
System.out.println("机器人工作");
}
}
定义一个人的类:
package com.wz.abstractdemo;
public class Human extends Action{
@Override
public void eat() {
System.out.println("人吃饭");
}
@Override
public void sleep() {
System.out.println("人睡觉");
}
@Override
public void work() {
System.out.println("人工作");
}
}
定义一个猪的类:
package com.wz.abstractdemo;
public class Pig extends Action{
@Override
public void eat() {
System.out.println("猪进食");
}
@Override
public void sleep() {
System.out.println("猪睡觉");
}
@Override
public void work() {
}
}
测试类:
package com.wz.abstractdemo;
public class AbstractDemo {
public static void main(String[] args) {
fun(new Robot());
fun(new Human());
fun(new Pig());
}
public static void fun(Action act){
act.commond(Action.EAT);
act.commond(Action.SLEEP);
act.commond(Action.WORK);
}
}
//运行结果:
//机器人充电
//机器人工作
//人吃饭
//人睡觉
//人工作
//猪进食
//猪睡觉
与我们之前采用多态设计的主人给宠物投食一样,只是使用抽象类更简单明了,我将改进的代码一律放在下面,对比前面讲继承时代码学习
需求:主人给不同的宠物投食,不同的宠物吃的食物不同
public class Text {
public static void main(String[] args) {
//创建主人对象
zhuRen ren=new zhuRen();
//创建小狗、小猫对象,然后向上转型成Pet类型
dog dg=new dog();
Pet dog=dg;
Cat ct=new Cat();
Pet cat=ct;
//然后主人投食
ren.feed(dog);//小狗正在啃骨头
ren.feed(cat);//小猫正在吃鱼
}
}
class zhuRen{
public void feed(Pet pet){
pet.eat();
}
}
abstract class Pet{
public abstract void eat();
}
class dog extends Pet{
public void eat(){
System.out.println("小狗正在啃骨头");
}
}
class Cat extends Pet{
public void eat(){
System.out.println("小猫正在吃鱼");
}
}