黑马程序员—继承,抽象类

来源:互联网 发布:维特斯数据 编辑:程序博客网 时间:2024/04/29 11:32

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

1.继承:
1.1:继承的由来:
在平时写代码的过程中,发现很多类都是具有共性的,将这些共性抽取出来变成一个父类,通过继承的方式来改进或者实现这些共性。
例如:
将学生和工人的共性描述提取出来,单独进行描述。
只要让学生和工人继承这个单独描述的这个类,就不需要再重写这些共性内容了。

1.2:继承的好处:
1.提高了代码的复用性。
2.让类与类之间产生了关系,有了这个关系,才有了动态的特性。

1.3继承需要注意的地方:
不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。
判断方式:父类中的内容是不是子类中都必须该具备的。
如下:

class A{    void demo1(){}    void demo2(){}}class B extends A{    void demo1(){}    void demo3(){}

这样继承是错误的,因为A里面的内容不是B都必须具备的,只有demo1
是共同的。
可以如下继承:

class c{    void demo1(){}}class A extends c{    void demo2(){}}class B extends c{     void demo3(){}}

1.4:单继承:
Java 语言中,只支持单继承,不支持多继承。
因为多继承容易带来安全隐患:当多个父类中定义了相同功能,当功能内容不同时,
子类对象不知道要运行哪一个。
但是java保留这种机制,并用另一种体现形式来完成表示,多实现。

java支持多层继承。也就是一个继承体系。

如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经基本可以使用了。
在具体调用时,要创建最子类的对象,为什么?
1.因为有可能父类不能创建对象。
2.创建子类对象可以使用更多的功能,包括基本的也包括特有的。
简单一句话概况:查阅父类功能,创建子类对象使用功能。

class Person{    String name;    int age;}class Student extends Person  // 学生是人的子类,人是学生的父类。{    void study()    {        System.out.println("good study");    }}class Worker extends Person //工人是人的子类,人是工人的父类。{    void work()    {        System.out.println("good work");    }}class  ExtendsDemo{    public static void main(String[] args)     {        Student s = new Student();        s.name="zhangsan";    }}

2.子父类中各成员的特点:
2.1:变量:
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super。

super的使用和this的使用几乎一致,
this代表的是本类对象的引用,
super代表的是父类对象的引用。

class Fu{    int num = 4;}class Zi extends Fu{    int num = 5;    void show()    {        System.out.println(super.num);  //super:超类,也是指父类。(相对this)    }}class ExtendsDemo2{    public static void main(String[] args)     {        Zi z = new Zi();        z.show();    }}

2.2:函数:
当子类出现和父类一模一样的函数时,
当子类对象调用该函数,会运行子类函数的内容。
如同父类的函数被覆盖一样。

这种情况是函数的另一个特性:重写(覆盖)。

当子类继承父类,沿袭了父类的功能到子类中。
但是子类虽然具备该功能,但是功能的内容和父类却不一致,
这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容。

覆盖(重写):
1.子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
2.静态只能覆盖静态,不能覆盖非静态。
(目前有三种访问权限:public>默认(什么都不写)>private。

注意:
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。

class Fu{    void show()    {        System.out.println("fu show");    }    void speak()    {        System.out.println("vb");    }}class Zi extends Fu{    void show()    {        System.out.println("zi show");      }    void speak()    {        System.out.println("java");    }}class ExtendsDemo2{    public static void main(String[] args)     {        Zi z = new Zi();        z.speak();          //显示内容是java。    }}
class Tel{    void show()    {        System.out.println("number");    }}class NewTel{    void show()    {        super.show();       //来电显示升级,利用覆盖的特性,方便操作。        System.out.println("name");        System.out.println("pic");    }}

2.3:构造函数:
在对子类对象进行初始化时,父类的构造函数也会运行,
那是因为子类的构造函数默认第一行有一条隐式的语句super();
super();会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();

为什么子类一定要访问父类中的构造函数。
因为父类中的数据子类可以直接获取,所以子类对象在建立时,
需要先查看父类是如何对这些数据进行初始化的
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数时,可以通过手动定义super语句的方式来指定。
注意:super语句一定要定义在子类构造函数的第一行。

子类的实例化过程:
结论:子类所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类每一个构造函数内的第一行都有一句隐式的super();

当父类中没有空参数的构造函数时,子类必须手动通过super或者this语句形式
来指定要访问的父类中的构造函数。

当然,子类的构造函数第一行也可以手动指定this一句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。

为什么this和super语句不能写在同一行?
因为它们都只能写在第一行。

为什么this和super语句都必须写在第一行?
因为必须最先开始初始化。

class Fu{    Fu()    {        System.out.println("fu run");    }}class Zi extends Fu{    Zi()    {        //super(); 调用父类构造函数,这句话是默认添加的。         System.out.println("zi run");    }    Zi(int x)    {        //super();         System.out.println("zi..."+x);    }}class ExtendsDemo2{    public static void main(String[] args)    {        Zi z = new Zi();        Zi z1 = new Zi(3);              }}

3.抽象类:当多个类中出现了相同功能,但是功能主体不同,
这是也可以进行向上抽取,这时只抽取功能定义,而不抽取功能主体。

抽象:所谓的看不懂。
抽象类的特点:
1.抽象方法一定定义在抽象类中。
2.抽象方法和抽象类都必须被abstract关键字修饰。
3.抽象类不可以用new创建对象,因为调用抽象方法没有意义。
4.抽象类中的抽象方法要被使用,必须要由子类复写其所有的抽象的方法后
建立子类对象调用,如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。

抽象类和一般类没有太大不同,该如何描述事物就如何描述事物,只不过该事物中出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出来,但是无法定义主体。
通过抽象方法来表示。

抽象类比一般类多了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。

特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

abstract class Student      //抽象方法必须存放在抽象类中{    abstract void study();          //absteact:抽象。}class BaseStudent extends Student{    void study()    {        System.out.println("base study");    }}class AdvStudent extends Student{    void study()    {        System.out.println("adv study");    }}class AbstractDemo{    public static void main(String[] args)    {        new BaseStudent.study();    } }

假如我们在开发一个系统时需要对员工进行建模,员工包含3个属性。
姓名、工号以及工资。经理也是员工,除了含有员工的属性外,另外还有一个
奖金属性。请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法
进行属性访问。

员工类:name id pay

经理类:继承了员工,并有自己特有的bonus。

class Employee{    private String name;    private String id;    private double pay;    Employee(String name, String id, double pay);    {        this.name = name;        this.id   = id;        this.pay  =pay;    }    public abstract void work();}class Manager extends Employee{    private int bonus;    Manager(String name, String id, double pay,int bonus);    {        super(name,id,pay);        this.bonus = bonus;    }    public void work()    {        System.out.println("manager work");    }}class Pro extends Employee{    Pro(String name, String id, double pay);    {        super(name,id,pay);    }    public void work()    {        System.out.println("pro work");    }}

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

0 0
原创粉丝点击