有关抽象类中的学习知识。
对于抽象类的特点概述。
-
1、// 抽象类中如果有抽象方法的话,继承该抽象类的子类(不为抽象类的子类),必须重写父类中所有的抽象方法。
-
2、// 即使是抽象类,如果用构造方法,里面的super还是会指向所继承的父类的。
-
3、// 抽象类和方法被static修饰的话,是不能被继承使用的。(所以用抽象的东西就不用static修饰。抽象类用来继承的。)
-
4、// 抽象类没有方法体:例子
public abstract void eat();
。 -
5、// 抽象类只能单继承。(一般使用接口来处理多继承的情况。)
abstract class A {
public static void show() {
System.out.println("hello");
}
}
public class TestChouXiangLei {
public static void main(String[] args) {
A.show();
}
}
//这里抽象类不用new(他也不能new,就可以直接对里面的非抽象方法进行调用。
输出为:hello
。
这里可以看出即使没有继承抽象类,也是不会报错的。只是看不出抽象类的作用。(这样写对于abstract类来说也没什么用。)
如果是调用内部抽象类的话。
abstract class NeiBuLei {
static abstract class Lei {//这里不加上static的话,就是会报需要包含NeiBuLei.Lei的封闭实例问题。
public abstract void print();//加上static就能跑了?
}
}
class ShiYong extends NeiBuLei.Lei {
//如果没有覆写内部类的抽象方法的话,会报需要覆盖抽象方法的错误。
@Override
public void print() {
System.out.println("成功使用内部抽象类中的print方法。");
}
}
public class TestChouXiangLei {
public static void main(String[] args) {
NeiBuLei.Lei lei = new ShiYong();
lei.print();
}
}
这里是不是跟上面讲的抽象类和方法不能被static修饰矛盾了。诶这里的内部类不是被static修饰了吗?
如果写成这样的话:
abstract class NeiBuLei {
static abstract class Lei {//这里不加上static的话,就是会报需要包含NeiBuLei.Lei的封闭实例问题。
public abstract void print();//加上static就能跑了?
}
}
class ShiYong extends NeiBuLei {
}
public class TestChouXiangLei {
public static void main(String[] args) {
NeiBuLei lei = new ShiYong();
}
}
//没有报错。
这里这样是看static修饰的抽象类是没有报错的。(可以看出,static还是可以修饰abstract类的。只不过不能实现继承。而抽象类和方法用处又在继承。所以就不拿static啊,final来修饰抽象类和方法。)
如果是子类不为抽象类的话。实现继承例子如下:
package com.Abstract;
/**
* 1、 这里是写了两个抽象方法,分别通过两个不同的子类来继承这个抽象父类,看输出。
* 2、通过多次继承来看看,不是抽象方法具有的特点。
*/
abstract class Action {
public Action() {
System.out.println("抽象类中的构造方法。");
}
public abstract void eat();
public abstract void drink();
}
class Person extends Action {
@Override
public void eat() {
System.out.println("人天天吃饭");
}
@Override
public void drink() {
System.out.println("人天天喝水");
}
}
class Cat extends Action {
@Override
public void eat() {
System.out.println("Cat吃鱼");//即使覆写的语句和父类中的抽象方法一样的话,也是可以的。不影响。
}
@Override
public void drink() {
System.out.println("Cat喝牛奶");
}
}
//一个继承了Person的子类,但是其中什么都没有写,来测试,不是抽象类的Person类。
class PersonMan extends Person {
}
public class ZiLeiBuWeiChouXiangLei {
public static void main(String[] args) {
Action cat = new Cat();
cat.eat();
cat.drink();
Action person = new Person();
person.eat();
person.drink();
}
}
输出为:
抽象类中的构造方法。
Cat吃鱼
Cat喝牛奶
抽象类中的构造方法。
人天天吃饭
人天天喝水
这里可以看出来,子类不为抽象类的话,就必须覆写抽象父类中的所有抽象方法不然会报错。(注意是抽象方法,不包括成员方法的。)然后子子类(也就是PersonMan类)是不需要覆写他的最高辈分类中的抽象方法的。(这是子类不为抽象类的一个特征。)
(可以测试一下,如果不写全父类中的抽象方法的话,结果会是怎么样。这里就把人吃饭的覆写的抽象方法删去。)
报错:
java: com.Abstract.Person不是抽象的, 并且未覆盖com.Abstract.Action中的抽象方法eat()
如果子类为抽象类呢?
package com.Abstract;
abstract class Act {
public Act() {
System.out.println("抽象类中的构造方法。");
}
public void show() {
System.out.println("父类抽象类中的show方法。");
}
public abstract void eat();
public abstract void drink();
}
//那也就是说,子类也为抽象类的话,可以不用覆写抽象父类的抽象方法。也不需要覆写抽象父类中的成员方法。
abstract class Per extends Act {
public void time() {
System.out.println("Per类中的time方法。");
}
public abstract void work();//这里写一个抽象方法,再设置一个子类,只在继承后覆写这一个方法,看会不会报错。
// @Override
// public void eat() {
// System.out.println("人天天吃饭");
// }
// @Override
// public void drink() {
// System.out.println("人天天喝水");
// }
}
abstract class Dog extends Act {
@Override
public void eat() {
System.out.println("Dog吃骨头");
}
@Override
public void drink() {
System.out.println("Dog喝水");
}
}
class Human extends Per {//我这里只是想继承Per类,明明重写了Per中的抽象方法work,也报错了。
public void work() {
System.out.println("人天天工作");
}
}
public class ZiLeiWeiChouXiangLei {
public static void main(String[] args) {
}
}
这里,我把子类全改为了抽象类。然后就发现是抽象类的子类。可以不覆写抽象父类中的抽象方法也是可以运行的。(所以我就转向了 子子类。)这里就发现。虽然Human子类覆写了Per父类的work抽象方法。不过还是报错了。
报错为:
java: com.Abstract.Human不是抽象的, 并且未覆盖com.Abstract.Act中的抽象方法drink()
既然报了没有覆盖父父类的drink方法的错误。那就加上drink();
@Override
public void drink() {
}
看行不行。
结果是,又报错了。
报错为:
java: com.Abstract.Human不是抽象的, 并且未覆盖com.Abstract.Act中的抽象方法eat()
所以这里就可以看出来。即使是跳了一辈分的子类(如果不是抽象类的话,不全覆写所以父辈的抽象方法,他就会报错。)这里也大概理解了子类不为抽象类和为抽象类的区别 :
1、是抽象子类对父类中的抽象方法不做要求。而不是抽象方法的子类就必须覆写抽象方法。
2、对与不是抽象方法的子类,需要覆写是抽象类中的所有父辈的抽象方法。
abstract class ChouXiang {
public int age;
private String name;
public static void main() {
System.out.println("语句一");
}
public static void main(int age) {
System.out.println("age=" + age);
}
public ChouXiang() {
System.out.println("父类中的无参构造方法。");
}
public ChouXiang(String name, int age) {
this.age = age;
this.name = name;
}
abstract void chouXiangFangFa(int age);
// abstract ChouXiang(int age) {
// }
这里的是想看看,是否内把抽象类的构造方法也给抽象了。
发现是不行的。会报错。
并且看一下,在抽象类中,成员属性是否能写在里面。(也是可以的。)也就是说,一个抽象类里面也可以没有抽象方法。(只是可能就失去是抽象类的意义了。)
然后是对于继承的关系了。由于抽象类只能是单继承。这就留到接口再说吧。