22天学习java基础笔记之day08

Day08     继承  final  抽象类    

一、继承

1、概述

        多个类中存在相同属性和行为时,将这些相同的内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。子类可以直接访问父类中的非私有的属性和行为。

2、特点

        A:Java只支持单继承,不支持多继承(子类调用父类方法的不确定性)。但是它支持多层继承(接口与接口之间可以存在多继承)

        B:父类有的,子类也有,而且子类可以改变(更改父类的属性值,重写父类的成员方法),父类没有的子类也可以进行增加。

        C:父类的属性和方法可以被继承,但是构造方法不能被继承,子类的构造方法隐式的调用父类的无参构造方法,当父类没有无参构造方法时,子类需要使用super来显示的调用父类的构造方法。

3、举例

-------学生类继承了人类,拥有了人类的成员变量(name和age)和成员方法(eat和sleep方法)

                class Person{

                        String name;

                        int age;    

                        Person(){}

                        public void sleep(){

                                System.out.println("睡觉");

                        }

                        public void eat(){

                                System.out.println("吃饭");

                        }

                }

                class Student extends Person{//学生继承人类

                        String sid;//学号

                        public void study(){

                                System.out.println("我宁愿做一头快乐的猪");

                        }

                }

4、研究继承后 FuZi的关系。

A:成员变量

                **子类直接继承了本身没有的成员变量。

                **当子类中有和父类同名的成员变量时。在方法中打印的是子类自己的。

                **当子类方法中有局部变量和成员变量同名,在方法中打印的是局部变量。

        也就是说:先在局部范围找,其次在本类中找,最后在父类中找。如果找到,立马输出。

如果找不到,就报错。

B:成员方法

        **父类中的方法和子类中没有同名的情况。子类就把父类的方法直接继承过来使用。

        **子类中存在了和父类同名的方法时,子类就会去调用子类中的方法。而且这种现象

在java中称为重写(override),复写,覆盖。

        重载(overload)与重写(override)的区别:

                重载(overload):

                        **在同一个类中。

                        **方法名相同,参数列表不同。

                重写(override)

                        **存在于子父类当中。

                        **方法的声明一致。(名称和参数)

                        **子类的访问权限不能低于父类的访问权限。

        简单说:用子类对象调用方法时,首先子子类中找,其次在父类中找。如果找到,会直接操作。如果找不到,就报错。

        父类静态方法只能被子类静态方法重写。(一般不会出现这种情况,静态属于类不再属于对象)

        注意:

                **父类中的私有方法不可以被覆盖。

                **在子类覆盖方法中,要想继续使用被覆盖的父类方法可以通过super.方法名获取。

                        格式:super.方法名();

This代表本类对象的引用。

Super代表父类所属的空间,并不是一个对象。

        C:构造方法

                **子类中所有的构造函数默认都会访问父类中空参数的构造函数

                **因为每一个构造函数的第一行都有一条默认的语句super();

                        this() 代表本类的无参构造

                        super() 代表父类的无参构造

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

为什么子类的构造函数都要去默认访问父类的构造函数?

因为子类继承了父类,可以访问父类中的已有的一些属性,在子类进行实例化的时候必须要为父类中的属性进行分配空间,并要进行初始化,所以必须要访问一次父类的构造函数,看看父类是如何对其属性进行初始化的,所以子类要实例化对象时,必须要先看父类的初始化过程。

结论:父类的构造函数,既可以给本类对象初始化,也可以给子类对象初始化。

5、什么时候使用继承?

        A:当某个事物是另一个事物的一种的时候,就用继承。

        B:如何判断一个事物是另一个事物的一种?

           对于A类和B类。

           我们可以假设它们存在着继承关系。比如:A extends B

        如果A是B的一种,那么继承成立。他们就具有继承关系。否则,继承关系不成立。

 

二、final

1final定义

最终的意思。

2、使用场景及特点

可以用于修饰类,修饰成员变量,成员方法。

        A:final修饰的类不能被继承。

        B:fainl修饰的成员方法不能被重写。

        C:final修饰的成员变量是一个常量。       

3、和变量声明的区别

final double PI = 3.14;

        A:多了一个关键字修饰。

        B:变量名大写。

        C:值不能被改变。

注意:用final修饰的变量必须先赋初始值再操作,否则编译失败。

三、抽象类

1、概述

        **抽象就是从多个事物中将共性的,本质的内容抽取出来。

        **Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。

        **多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,

        那么只有功能声明,没有功能主体的方法称为抽象方法。

2、特点

        **抽象类和抽象方法都必须用abstract关键字修饰。

        **抽象方法一定要在抽象类中。

        **一个类继承了抽象类:

                要么该类实现抽象类中的所有抽象方法。

                要么该类实现部分抽象方法或者根本不实现任何抽象方法,这个时候需要把自身定义为抽象类。

        **抽象类不能够被实例化。也就是说不可以通过new关键字创建对象。

                为什么抽象类不能被实例化?

                因为抽象类中有抽象方法,你创建对象后,别人调用抽象方法是没有任何意义的。

        **有人说:因为抽象类没有构造方法是错误的。

那么抽象类的构造有意义吗?有。

        抽象类本身是一个类,所有它有构造方法。它不能实例化不代表它的构造方法没有意义。它可以用于为子类对象进行实例化

3、应用

        雇员示例

需求:公司中程序员有姓名,工号,薪水,工作内容。

          项目经理除了有姓名,工号,薪水,还有奖金,工作内容。对给出需求进行数据建模。

数据建模:就是把我们给出的事物描述出来。说白了就是把类给设计出来。 

        我想让项目经理继承程序员。

        这是时候,我们说项目经理的是程序员的一种,发现可以。

        但是呢,分析又有小问题了:项目经理的工作内容和程序员不一样。

        不管怎么说:程序员和经理都是公司的员工。

        所以,我们分析出一个员工类,来描述共性的内容。

        然后把程序员和经理具体的描述下。                                  

代码:

abstract class Employee{

String name;//姓名

String id;//工号

double salary;//薪水                                        

Employee(){}                         

Employee(String name,String id,double salary){

this.name = name;

this.id = id;

this.salary = salary;

}                                     

abstract void work();//工作内容

abstract void showInfo();//个人信息

}                             

class Worker extends Employee{

Worker(){}                                     

Worker(String name,String id,double salary){

super(name,id,salary);

}                                     

void work(){

System.out.println("好好学习,天天向上");

}                                     

void showInfo(){

System.out.println(name+"   "+id+"   "+salary);

}

}                                     

class Manager extends Employee{

        double bonus;//奖金        

        Manager(){}

        Manager(String name,String id,double salary,double bonus){

                super(name,id,salary);

                this.bonus = bonus;

        }

        void work(){

                System.out.println("想怎么着能让你更大的能量(更累,累并快乐着)");

        }

        void showInfo(){

                System.out.println(name+"   "+id+"   "+salary+"   "+bonus);

        }

}                             

class AbstractDemo5 {

        public static void main(String[] args) {

                Worker w = new Worker("慈禧","cixi888",10000);

                w.work();

                w.showInfo();

                Manager m = new Manager("李莲英","lilianyin250",2000,16000);

                m.work();

                m.showInfo();

        }

}

4、细节

        A:抽象类中是否有构造方法?

                **因为抽象类它本身也是一个类,所以它有构造方法。

                **虽然它不能够被实例化,但是它的构造方法也是有用的。用于给子类做初始化。

        B:抽象类中可不可以没有抽象方法?

                **可以的。

                **有什么用?让类不能够被实例化。在awt里面有体现。

        C:抽象关键字abstract不可以和哪些关键字共存?

                **final 它修饰的方法不能被重写。而这样就和抽象产生了冲突。

                        ***final abstract void show(); 这是不行的。

                **private 它修饰内容只能在本类中被访问。

                        ***private abstract void show(); 这是不行的。

                **static 它修饰的内容可以直接被类访问,而访问抽象的内容没有意义。

                        ***static abstract void show(); 这是不行的。

原文地址:https://www.cnblogs.com/aohongzhu/p/12938756.html