为什么会产生抽象类,抽象类的定义,方法及使用原则

首先为什么会有抽象类和接口的产生?
当提到这里时必须先讲一讲方法覆写

方法覆写:定义了方法名称,返回值类型,参数的类型及个数完全相同,
被覆写的方法不能有比子类更为严格的访问控制权限。

方法覆写:多态的关键所在。
所以为了强制要求子类必须覆写父类方法产生了抽象类与接口.

多态:一个类实例的相同方法在不同情形下有不同的表现形式。

回顾:
向上转型:参数统一化

父类 父类引用 = new 子类实例();
father per = new Student();

向下转型:要发生向下转型必须先发生向上转型

子类 子类引用 = (子类) 父类实例;
Student stu = (Student) per;

所以不管是向上转型还是向下转型都发生了方法覆写。

抽象类说明符abstract:

一个类被声明为abstract,则表示该类是无具体对象的抽象类,
即该类不能进行实例化操作.不能用new关键字创建该类的对象,
只能由其子类的抽象方法的具体实现来完成.

抽象类:

Abstract:

定义:抽象类是普通类的超级,只是比普通类多了一些抽象方法而已。

首先知道:
抽象方法:使用抽象方法定义的只有方法声明没有方法体的方法.
语法:

public abstract void test();
//只有方法声明,没有方法体的方法

- 抽象类中包含抽象方法,则抽象类也必须使用abstract来定义,表示抽象类

本地方法(Java调用c同名方法):使用native定义的只有方法声明没有方法体的方法。

public native int hashCode();

注意:只有方法声明没有方法体的方法就是抽象方法(×)
因为在Java中还有native(本地方法);

抽象类的使用限制或者使用原则

(抽象类一定不能new)

  • a.所有抽象类必须有子类(final与abstract不能同时出现)
    原因:abstract一定有子类,而final一定没有子类(不能继承)。 (final可以修饰类)

因为由子类的抽象方法的具体实现来完成。
例子:

//具体定义
abstract class Person{
    private String name;
    private int age;
    public void setName(String name){
        this.name = name;
    }
    //只声明而为实现的方法(不能直接使用,只能由子类的抽象方法来实现完成)
    public abstract void getPerson();
}
public class Test{
    public static void main(String[] args) {

    }
}
  • b.抽象类的子类必须覆写所有抽象方法(或者子类也使用abstract关键字定义)
定义抽象类的目的就是想让类继承,实现覆写

private与abstract不能同时出现,抽象方法必须被覆写而private方法无法被覆写
  • c.抽象类方法无法直接产生实例化对象,但可以通过子类向上转型进行实例化。

(解释:抽象类是“半成品”,不能直接new 自己;由于存在向上转型,如果子类是一个普通类,可以把他变为抽象类进行使用)
且子类依然遵循对象实例化流程,先调用抽象类构造方法而后再调用子类构造。
(解释:先调用父类构造,产生父类对象,才有子类对象)
(抽象类是普通类的超级,普通类有构造方法,那抽象类一定有构造方法)

- d.抽象类可以没有抽象方法,但是此时任然不能直接实例化对象。
例子:

//具体定义
abstract class Person{
    private String name;
    private int age;
    public void setName(String name){
        this.name = name;
    }
    //只声明而为实现的方法(不能直接使用)
    public abstract void getPersonInfo();
}
class Student extends Person{
    public void getPersonInfo(){
        System.out.println("111");
    }
}
public class Test{
    public static void main(String[] args) {
        //通过向上转型,把Student对象指向了一个父类的引用
        Person per = new Student();
        //这时调用per.getPersonInfo();执行输出
        per.getPersonInfo();
    }
}

笔试题:

//请问输出是多少?
A.0
B.30
C.100
D.编译错误

abstract class Person {
    public Person() {
        this.print();
    }
    public abstract void print();
}    
class Student extends Person{
    private int num = 100;
    public Student(int num){
        this.num = num;
    }
    public void print(){
        System.out.println(num);
    }
}
public class Test{
    public static void main(String[] args) {
        new Student(30);
    }
}

输出:A.0

解释:
一:**从入口开始看**,
第一步调用子类Student这个类的构造方法,将30传值,但是
在**子类构造中有一个隐藏的super();(因为继承关系)**,所以先调用
父类构造方法再到子类。故当调用子类这个有参构造时连方法都进不去。
二:所以先在父类(**本质上第一步从父类开始**),Person的无参构造
调用了print方法(this表示本类对象),this在父类中,且用abstract关键字修饰,
所以此时print方法调用不了。
三:故去寻找子类中有无print方法,至子类中的print方法中,
子类的print方法覆写了父类,故从子类的覆写后的方法进行输出,
此时的num还未进行this.num = num;这一行的赋值。
四:实际上private int num = 100;这一行在编译的时候在构造方法中执行,
但是在主方法中有new,所以开辟了一块新空间,所有属性都有默认值,故输出结果为0;

扩展:

扩展:
public class Test{
    public static void main(String[] args) {
        new Student(30).print();
    }
}

输出0,30

此时Student这个构造方法已经全部执行完成,最后才调用print方法,
print方法是通过子类Student类new调用,print方法被覆写,
所以调用的一定是被覆写后的方法。(先等于100,在等于30),
故输出30.

例子:

abstract class Person{
    public abstract void print();
    //在抽象类内部提供了一个实现好的子类,
    //(静态方法可通过类名称直接调用)
    public static Person getInstance(){
        //方法内部类,继承了抽象类并实现,
        //方法返回了实现好的子类
        class Student extends Person{
            public void print(){}
        }
        return new Student();
    }
}

public class Test{
    public static void main(String[] args) {
        Person per = new Student();
        per.print();
    }
}
  • 匿名内部类:等同于方法内部类,就是没有名字,但是匿名内部类必须继承一个抽象类或者实现一个接口,除此之外与方法内部类完全一致

例子:

abstract class Person{
    public abstract void print();
    //在抽象类内部提供了一个实现好的子类(静态方法可通过类名称直接调用)
    public static Person getInstance(){
        //匿名内部类,隐藏了没有名字的类
        //等同于class 无名 extends Person{}
        //直接实例化:new Person();
        return new Person(){
            //内部类
            public void print(){}
        }
    }
}

.

猜你喜欢

转载自blog.csdn.net/qq_43464809/article/details/89255395