一、面向对象——继承概述
(1)继承的概念:继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。(网络释义) (2)继承的作用: 1、提高了代码的复用性; 2、让类与类之间产生了关系,有了这个关系,才有了多态的特性。 示例代码:class Person //父类 { String name; int age; } class Student extends Person //子类 { void study() { System.out.println("study"); } } class Worker extends Person //子类 { void work() { System.out.println("work"); } }
(3)注意:
1、千万不要为了获取其他类的功能、简化代码而继承;
2、必须是类与类之间有所属关系才可以继承。二、面向对象——继承概述2
1、注意:
java语言中,只支持单继承,不支持多继承。因为多继承容易带来安全隐患:当多个父类中定义了相同功能,但功能内容不同时,子类不确定该运行哪一个。
示例代码:class A { void show() { System.out.println("a"); } } class B { void show() { System.out.println("b"); } } class C extends A,B//不可以多继承。 {} class Demo { public static void main(String[] args) { new C().show();//此时不知道该运行哪一个show()方法; } }
2、java支持多层继承,也就是一个继承体系
class A
{}
class B extends A
{}
class C extends B
{}
此时,C对象同时具备了A和B的功能;
那么如何使用一个继承体系的功能呢?
想要使用体系,先查阅体系父类的描述。因为父类中定义的是该体系中的共性功能;通过了解共性功能,就可以知道该体系的基本功能。
在调用时,应创建最子类的对象。因为有可能父类不能创建对象;而且创建子类对象可以使用更多的功能,包括基本功能和特有功能。
简单的说:查阅父类功能,创建子类对象使用功能。三、面向对象——聚集关系
聚合:指的是整体与部分的关系。
组合:也表示类之间整体和部分的关系,但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在,部分对象也将不存在。部分对象与整体对象之间具有共生死的关系。
========请查阅相关资料。四、面向对象——子父类中变量的特点
1、成员变量:
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用 this. ;
子类要访问父类中的同名变量,要用 super.
this 代表的是本类对象的引用;
super 代表的是父类对象的引用。
示例代码:class Fu { int num = 4; } class Zi extends Fu { int num = 5; void show() { System.out.println(super.num); //super代表父类的引用 } } class ExtendsDemo { public static void main(String[] args) { Zi z = new Zi(); System.out.println(z.num);//5 z.show();//4 } }
注意:
加载子类时,会先加载父类。五、面向对象——子父类中函数的特点——覆盖
1、概念:
当子类出现和父类一模一样的函数时,子类对象调用该函数,会运行子类函数的内容,如同父类的函数被覆盖一样。这种情况就是函数的另一个特性——覆盖(重写)。
示例代码:class Fu { void show() { System.out.println("fu run"); } } class Zi extends Fu { void show() { System.out.println("zi run"); } } class ExtendsDemo { public static void main(String[] args) { Zi z = new Zi(); z.show();//结果zi run } }
重写使用的场景
当子类继承父类,沿袭了父类的功能到子类中;但是子类虽具备该功能,但是功能的内容却和父类不一致;
这时,没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义,并重写功能内容。
2、注意:
A、子类覆盖父类,必须保证子类权限大于等于父类权限;
B、静态只能覆盖静态。
3、重写的作用:
重写还可以用于功能的拓展。
4、注意:
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。六、面向对象——子父类中构造函数的特点——子类实例化过程
1、特点:
在对子类对象进行初始化时,父类的构造函数也会运行; 因为子类的构造函数默认第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是 super();
2、子类一定要访问父类中的构造函数的原因:
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的;
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义 super 语句的方式来指定。
3、注意:
super 语句一定定义在子类构造函数的第一行。
4、结论(子类的实例化过程):
A、子类的所有的构造函数,默认都会访问父类中空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式 super();
B、当父类中没有空参数的构造函数时,子类必须手动通过 super 语句形式来指定要访问父类中的构造函数。
C、当然:子类的构造函数第一行也可以手动指定 this 语句来访问本类中的构造函数。
D、如果子类中的第一行有 this(); 语句,就没有了隐式是 super(); 语句。
E、子类中至少会有一个构造函数会访问父类中的构造函数。
5、子类调用父类是构造函数用 super() ; 子类调用父类的一般函数用 super.函数名
示例代码:class Fu { int num; Fu() { num = 60; System.out.println("Fu run"); } Fu(int x) { System.out.println("x="+x); } } class Zi extends Fu { Zi() { //super();//隐式语句 //super(3);//手动指定 System.out.println("Zi run"); } Zi(int x) { System.out.println("zi....."+x); } } class ExtendsDemo { public static void main(String[] args) { Zi z = new Zi(); //结果:Fu run; Zi run; System.out.println(z.num); //结果60;因为子类拿到了父类中的初始化值。 Zi z1 = new Zi(10); //fu run; zi....10 } }
七、面向对象——final关键字
(1)final的特点:
1、 final 可以修饰类、方法、变量;
2、 final 修饰的类不可以被继承;
3、 final 修饰的方法不可以被覆盖;
4、 final 修饰的变量是一个常量,只能被赋值一次;既可以修饰成员变量,又可以修饰局部变量。
5、内部类只能访问被 final 修饰的局部变量。
(2) final 修饰变量的应用:
当在描述事物时,一些数据出现的值是固定的,这时为了增强阅读性,都给这些值起个名字,方便于阅读。而这个值不需要改变,所以加上 final 修饰作为常量。
常量的书写规范:所有字母都大写;如果有多个单词组成,单词间通过_连接。
例如: final double MY_PI = 3.14;
全局常量: public static final double PI = 3.14;
注意:
继承的出现打破了封装性。八、面向对象——抽象类
(1)概念:
当多个类中出现相同功能,但是功能主体不同,这时可以进行向上抽取,并只抽取功能定义,而不抽取功能主体。所抽取出的功能叫抽象方法。
含有抽象方法的类称为抽象类。
(2)抽象类的特点:
1,抽象方法一定在抽象类中;
2,抽象方法和抽象类都必须被 abstract 关键字修饰;
3,抽象类不可以用 new 创建对象。因为调用抽象方法没意义;
4,抽象类中的抽象方法要被使用,必须由子类复写其所有的抽象方法后,建立子类对象调用;
5、如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
示例代码:abstract class Student { abstract void study(); }
九、面向对象——抽象类2
1、理解抽象类:
抽象类和一般类没有太大的不同。该如何描述事物,就如何描述事物,只不过,该事物出现了一些不确定的东西。
这些不确定的部分,也是该事物的功能,需要明确出现,但是无法定义主体,需通过抽象方法来表示。
抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。抽象类不可以实例化。
2、注意:
抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。十、面向对象——抽象类练习
需求:
假如我们在开发一个系统时需要对员工进行建模,员工包含 3 个属性:姓名、工号以及工资。
经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
分析:
员工分为普通员工和经理
员工类:name id pay;工作方法抽象
普通员工类:继承员工;
经理类:继承了员工,并有自己特有的bonus。
代码如下:abstract 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 Pro extends Employee { Pro(String name, String id, double pay) { super(name,id,pay); } public void work() { System.out.println("pro 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"); } }
十一:面向对象——模板方法模式
1、概念:
在定义功能时,功能的一部分是确定的,但是有一部分是不确定,而确定的部分在使用不确定的部分;
那么这时就将不确定的部分暴露出去,由该类的子类去完成,确定的部分可以用 final 修饰。
示例代码:abstract class GetTime { public final void getTime() { long start = System.currentTimeMillis(); runcode(); long end = System.currentTimeMillis(); System.out.println("毫秒:"+(end-start)); } public abstract void runcode(); } class SubTime extends GetTime { public void runcode() { for(int x=0; x<1000; x++) { System.out.print(x); } } } class TemplateDemo { public static void main(String[] args) { SubTime gt = new SubTime(); gt.getTime(); } }
十二、面向对象——接口
1、初期理解:
如果抽象类中的抽象方法都是抽象的,那么该类可以以接口的形式来表示。
2、格式:
interface {}
3、接口中成员的特点:
接口中的常见定义:常量、函数
接口中的成员修饰符是固定的:
成员常量: public static final
成员函数: public abstract
接口中,如果该成员的缺少修饰符,则系统会自动加上。
4、注意:
A、接口不可以创建对象,因为有抽象方法;
B、子类对接口中的抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类;
C、接口的成员都是 public 的,所以其子类在覆盖接口方法时,子类的方法必须都是 public 。
5、接口中不可以定义变量,其属性都是常量。
6、注意:抽象类和一般类只能实现接口,不能继承接口。
示例一:interface Inter { public static final int NUM = 3; public abstract void show(); } class Test implements Inter { public void show(){} }
示例二:interface Person { public static final int NUM = 4; public abstract void speak(); public abstract void show(); } abstract class Student implements Person { public void speak() { System.out.println("speak..chinese!"); } public abstract void show(); } class BaseStudent extends Student { public void show() { System.out.println("show---"); } } class Demo4 { public static void main(String[] args) { BaseStudent bs = new BaseStudent(); bs.speak(); bs.show(); System.out.println(bs.NUM); //4 System.out.println(Person.NUM); //4 System.out.println(Student.NUM); //4 System.out.println(BaseStudent.NUM); //4 } }
十三、面向对象——接口2
1、接口作用:
接口的出现,将“多继承”通过另一种形式体现出来,即“多实现”。
示例:interface InterA { public static final int NUM = 3; public abstract void show(); } interface InterB { public abstract void show(); } class Demo{} class Test extends Demo implements InterA,InterB//子类可以在继承一个父类的同时,还可以实现接口 { public void show(){}//两个接口有相同的方法时,覆盖一个即可。 }
2、注意:
接口与接口之间可以继承。
示例:interface A {} interface B extends A {} interface C extends B {}
接口与接口之间可以多继承:interface A {} interface B {} interface C extends A,B {}
十四、面向对象——接口的特点
1、接口是对外暴露的规则;
2、接口是程序的功能扩展;
3、接口可以用来多实现;
4、类与接口之间是实现关系,而且类可以在继承一个类的同时实现多个接口;
5、接口与接口之间可以有继承关系,而且支持多继承;十五、面向对象——接口举例体现
继承和实现的区别:
继承——子类所属于父类:is a
接口——父类是子类的扩展功能:like a
代码:interface Smoking { void smoke(); }//扩展功能 abstract class Student { abstract void study(); void sleep() { System.out.println("sleep"); } }//基本功能 class Boy extends Student implements Smoking { void study(){} public void smoke(){} }