Java -- 面向对象【抽象类】
今天我们来说一下抽象类,这算是开始步入Java高级阶段的门了,由浅入深,慢慢的接触Java的核心技术,今天乃至于以后的学习都是以前面的基础作为铺垫的,也可以说是 ---- “啃老本”,所以掌握好基础的语法知识至关重要,加油吧,老鸟在前面等着我们去追赶呢O(∩_∩)O哈哈~!!!
雄起~
通常可以说四边形有4条边,或者再具体一些的话,就是平行四边形是具有对边平行且相等特性的特殊的四边形,等腰三角形是其中两条边相等的三角形,这些都是描述的合乎情理的,但是对于图形对象却不能使用具体的语言进行描述,他有几条边,是什么形状,没人能说清楚,这种类在java中被称为抽象类
1、概述
Java中可以定义没有方法体的方法,该方法由其子类来具体的实现。该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。抽象类可以理解为是一个只有方法声明没有方法体的特殊类。
2、特点
- 通过java关键字abstract实现;
- 可以修饰方法或者类;
- 抽象类中可以没有抽象方法(由子类去实现);
- 如果类中有抽象方法,那该类必须定义为一个抽象类;
- 子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写;
- 多用于多态中;
- 抽象类不可以被实例化
3、入门案例
package cn.tedu.abstractdemo;
//这个类用来测试抽象类
public class Test_Abstract {
public static void main(String[] args) {
//创建多态对象
// Animal animal = new Animal();//6、抽象类不能被实例化
Animal animal = new Dog();//父类引用指向子类对象,多态--向上转型
//编译看左边,只能用父类提供的功能,父类就是标准
animal.eat();
animal.sleep();
animal.game();//7、子类重写了抽象方法,
//存在方法重写,运行看右边,也就是结果向子类看齐
}
}
//父类:把子类的共性功能,向上提取,形成父类,提高代码复用性
//2、如果一个类中包含了抽象方法,那么这个类必须声明为抽象类
//class Animal{
abstract class Animal{//抽象类
//1、子类发生了方法重写,也就是把父类的方法体改掉了!!
// public void eat() {
// System.out.println("吃啥都行");
// }
//此时父类提供的方法体有点多余,父类干脆不提供方法体了!! -- 叫抽象方法
public abstract void eat();//抽象方法 --- 用关键字abstract修饰
public abstract void game();//抽象方法 --- 用关键字abstract修饰
public void sleep() {
System.out.println("正在睡觉");
}
}
//创建子类
//3、子类继承了一个抽象类以后,可以是抽象的子类,也可以是普通的子类(需要把所有抽象方法都重写)
//方法 ①
//将子类也设置为抽象类属性
abstract class Cat extends Animal{
//4、Cat已经把父类的所有方法都继承过来了,此时包含抽象方法
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("本喵只吃鱼");
}
//只要包含抽象方法,就一定是一个抽象类
}
//方法 ②
//5、如果想当普通子类,需要重写所有抽象方法,
class Dog extends Animal{
//重写:方法声明和父类一样,要改的知识方法体!!
@Override
public void eat() {
System.out.println("我只吃肉");
}
public void game() {
System.out.println("狗抓耗子");
}
}
4、抽象类的用法
(一)构造函数
- 抽象类也有构造方法,但是不能本身实例化。
package cn.tedu.abstractdemo;
public class Test2_UseAbstract {
//这个类用来测试抽象类---构造方法的使用
public static void main(String[] args) {
//创建多态对象
//3、创建子类对象时,为什么会触发父类的无参构造?-- 因为子类无参构造中,隐藏着super()
AbstractDemo ad = new AbstractDemo2();
//4、抽象类是不能创建对象的,那还提供构造方法干嘛呢? -- 不是为了自己创建对象,而是为了子类创建对象用
// AbstractDemo ad2 = new AbstractDemo();
}
}
//创建抽象类
abstract class AbstractDemo{
//1、提供构造方法 -- 修饰符 类名([参数列表]){...} -- 创建对象时调用
public AbstractDemo(){
System.out.println("AbstractDemo()...无参构造");
}
//2、如果抽象类中没有抽象方法,那这个类修饰成普通类就可以,为什么还是被修饰成抽象类
//---目的就是不让外界创建对象
}
//创建子类
class AbstractDemo2 extends AbstractDemo{
public AbstractDemo2() {
//3、子类的无参构造中,第一条语句隐藏着super()
super();
System.out.println("AbstractDemo2()...无参构造");
}
}
问题一:创建子类对象时,为什么会触发父类的无参构造?
------ 因为子类无参构造中,隐藏着super()
-
问题二:抽象类是不能创建对象的,那还提供构造方法干嘛呢?
------ 不是为了自己创建对象,而是为了子类创建对象用
(二)抽象类的成员变量
- 既可以有变量,也可以有常量。
package cn.tedu.abstractdemo;
public class Test3_UseAbstract {
//这个类用来测试,抽象类的成员变量的使用
public static void main(String[] args) {
//创建多态对象测试
AbstractDemo3 demo = new AbstractDemo4();
System.out.println(demo.sum);
System.out.println(AbstractDemo3.MIN_VALUE);//静态资源用类名来调用
}
}
abstract class AbstractDemo3{
//1、抽象类中,可以包含变量,也可以包含常量!!
int sum = 10;
static final int MIN_VALUE = -128;//常量
}
class AbstractDemo4 extends AbstractDemo3{
}
(三)抽象类的成员方法
- 抽象类里,既可以有普通方法,也可以有抽象方法。
package cn.tedu.abstractdemo;
//这个类用来测试 抽象类的成员方法的使用
public class Test4_UseAbstract {
public static void main(String[] args) {
//3、创建多态对象测试
AbstractDemo5 demo5 = new AbstractDemo6();
demo5.eat();
demo5.play();
demo5.study();
}
}
//1、抽象类是一个特殊的类,特殊在哪? -- 抽象类可以有普通方法,也可以有抽象方法
abstract class AbstractDemo5{
//4、抽象类可不可以都是普通方法?
//5、抽象类可不可以都是抽象方法?
public void eat() {
System.out.println("大家吃的都是一样的");
}
abstract public void play();
abstract public void study();
}
//2、如果子类继承了抽象的父类,子类有几条路?要么把所有抽象方法都重写,要么就是抽象的子类
class AbstractDemo6 extends AbstractDemo5{
@Override
public void play() {
System.out.println("打球");
}
@Override
public void study() {
System.out.println("好好学习");
}
}
【概念分析】
在解决实际问题时,一般将父类定义为抽象类, 需要使用这个父类进行继承与多态处理,回想继承和多态原理,维承树中越是在上方的类越抽象,如鸽子类继承鸟类、鸟类维承动物类等。在多态机制中,并不需要将父类初始化对象,我们需要的只是子类对象。所以在java语言中设置抽象类不可以实例化对象,因为图形类不能抽象出任何一种具体图形, 但它的子类却可以。
【下篇预告】
- 接口的一般用法与复杂使用
上一篇: Java基础知识 四 方法
下一篇: php编程中网页之间的变量传递