面对对象高级01
- 继承(重点)
- final 关键字(重点)
- static 关键字(重点)
- 工具类 思想(了解)
一、继承
1.1继承入门
继承是面向对象三大特征之一。(封装,继承,多态)
- 什么是继承?
DNA、龙生龙、凤生凤、老鼠的儿子会打洞?
- java为什么要继承?
概念:
可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
继承的格式
- 格式:public class 子类名 extends 父类名 { }
- 范例:public class Zi extends Fu { }
- Fu:是父类,也被称为基类、超类
- Zi:是子类,也被称为派生类
代码演示
public class Fu {
public void show() {
System.out.println("show方法被调用");
}
}
public class Zi extends Fu {
public void method() {
System.out.println("method方法被调用");
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Fu f = new Fu();
f.show();
Zi z = new Zi();
z.method();
z.show();
}
}
测试结果:
show方法被调用
method方法被调用
show方法被调用
总结
-
子类可以有父类的内容
-
子类还可以有自己特有的内容
1.2继承的好处和弊端
1.2.1好处
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
1.2.2弊端
- 继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类实现也不得不跟着变化,削弱了子类的独立性
软件设计的一项原则: 高内聚,低耦合
继承中成员的访问特点
高内聚: 内聚指的是实现功能的能力,高内聚是指实现功能的能力 越强越好,一个类应该只包含单一的职责,并且该职责被完整地封装在这个类中。
低耦合: 类与类之间的关联越少越好. 关联太多,导致维护困难.
(举例: 交了很多烂朋友,经常给你惹事,找你借钱.)
1.2.3什么时候使用继承(重点)
-
继承体现的关系:is a
-
假设法:我有两个类A和B,如果他们满足A是B的一种,或者B是A的一种,就说明他们存在继承关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承
-
举例:苹果和水果,猫和动物,猫和狗
is a 的关系 谁是谁的一种!
正例: 老师 是 人类 的一种
小轿车 是 汽车的一种
客运飞机 继承 飞机
战斗机 继承 飞机
反例:
张三是人,李四是人。
飞机可以飞行
鸟也可以飞行
鸟 继承 飞机 ? 合适吗?
1.3 总结:
- 继承的好处和弊端?
- 何时适合使用继承?
1.4 继承中成员访问特点
1.4.1 成员变量访问特点
public class Fu {
//技能
public String skill = "吃饭、睡觉、打豆豆";
}
public class Zi extends Fu {
//1姓名
public String name = "张三";
//2技能
// public String skill = "吃饭、睡觉、打豆豆、挖地道";
//
public void show() {
// 3
// String skill = "写代码";
System.out.println(name);
System.out.println(skill);
// 4
// System.out.println(tang);
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z = new Zi();
z.show();
}
}
结论
就近原则!
- 成员变量,子类父类都有,用子类的
- 成员变量,子类有,父类都没有,用子类的
- 成员变量,子类有,父类都没有,方法里又定义赋值了,用新定义的
- 成员变量,子类、父类、方法里都没有,玩屁呀。报错。
- (不考虑父亲的父亲…)
1.4.2 super关键字
package com.itheima.test2;
public class Fu {
//技能
public String skill = "吃饭、睡觉、打豆豆";
public void eat(){
System.out.println("一天三顿饭!");
}
public Fu(){
System.out.println("Fu出生了");
}
}
package com.itheima.test2;
public class Zi extends Fu {
//1姓名
public String name = "张三";
//2技能
// public String skill = "吃饭、睡觉、打豆豆、挖地道";
// 5super
public String skill = super.skill+"、挖地道";
public void show() {
// 3
// String skill = "写代码";
System.out.println(name);
System.out.println(skill);
// 4
// System.out.println(tang);
// 5.supper
super.eat();
}
public Zi(){
super();
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z = new Zi();
z.show();
}
}
测试结果:
Fu出生了
张三
吃饭、睡觉、打豆豆、挖地道
一天三顿饭!
结论
super 关键字的用法和 this 关键字的用法相似
- **this:**代表调用该方法的对象(一般我们是在当前类中使用this,所以我们常说this代表本类对象的引用)
- super:代表父类存储空间的标识(可以理解为父类对象引用)
1.4.3 构造方法访问特点
准备+演示test2
package com.itheima.test2;
public class Fu {
//技能
public String skill = "吃饭、睡觉、打豆豆";
public void eat(){
System.out.println("一天三顿饭!");
}
public Fu(){
System.out.println("Fu出生了");
}
public Fu(String ku){
System.out.println("Fu出生了"+ku);
}
}
package com.itheima.test2;
public class Zi extends Fu {
//1姓名
public String name = "张三";
//2技能
// public String skill = "吃饭、睡觉、打豆豆、挖地道";
// 5super
public String skill = super.skill+"、挖地道";
public void show() {
// 3
// String skill = "写代码";
System.out.println(name);
System.out.println(skill);
// 4
// System.out.println(tang);
// 5.supper
super.eat();
}
public Zi(){
super("大声哭泣");
System.out.println("儿子出生了");
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z = new Zi();
z.show();
}
}
测试结果:
Fu出生了大声哭泣
儿子出生了
张三
吃饭、睡觉、打豆豆、挖地道
一天三顿饭!
结论
-
子类中所有的构造方法默认都会访问父类中无参的构造方法
-
每一个子类构造方法的第一条语句默认都是:super()!super()只能出现在构造第一行。
-
**super(参数)**调用有参构造器。
-
细节:
所有类默认都有一个无参构造器,方便阅读代码,在使用super()的时候,自己定义无参构造器!
1.4.4 成员变量访问特点
package com.itheima.test3;
public class Fu {
public void show() {
System.out.println("show方法被调用");
}
}
package com.itheima.test3;
public class Zi extends Fu {
public void method() {
System.out.println("method方法被调用");
}
public void show() {
super.show();
System.out.println("Zi中show()方法被调用");
}
}
package com.itheima.test3;
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z = new Zi();
z.method();
z.show();
// z.test();
}
}
结论
就近原则!
- 成员方法,子类父类都有,用子类的
- 成员方法,子类有,父类都没有,用子类的
- 成员方法,子类有,父类都没有,方法里又定义赋值了,用新定义的
- 成员方法,子类、父类、方法里都没有,玩屁呀。报错。
- (不考虑父亲的父亲…)
1.5 方法重写
什么是方法重写:
子类重写父类方法即为重写。(要求:这个方法的修饰符、返回值、参数都一致,只有方法体不同!)
准备+演示test3
package com.itheima.test3;
public class Fu {
public void show() {
System.out.println("show方法被调用");
}
}
package com.itheima.test3;
public class Zi extends Fu {
public void method() {
System.out.println("method方法被调用");
}
public void show() {
super.show();
System.out.println("Zi中show()方法被调用");
}
}
package com.itheima.test3;
public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z = new Zi();
z.method();
z.show();
// z.test();
}
}
结论
补充:
快捷键alt+insert 补充@Override
什么是注解:
- 在类或者方法或者成员变量上加的@Xxx
- 加强代码编译前校验 或 加强功能 或 描述 等功能
@Override 作用: 加强代码编译前校验 和 描述功能!
什么是方法重写:
子类重写父类方法即为重写。(要求:这个方法的修饰符、返回值、参数都一致,只有方法体不同!)
1.6 继承规范(重点)
- Java中类只支持单继承,不支持多继承
- Java中类支持多层继承
1.7 继承小结
什么是继承、关键字是什么?
- 可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。
- extends
什么时候用继承?
- is a原则!(例如:学生是人的一种,飞机是交通工具的一种,猴子是动物的一种)
继承的成员访问原则?
- 就近原则
super的应用!
什么是重写?
子类重写父类方法即为重写。(要求:这个方法的修饰符、返回值、参数都一致,只有方法体不同!)
继承规范!
- Java中类只支持单继承,不支持多继承
- Java中类支持多层继承
1.8 继承案例
1.8.1 老师和学生
需求:定义老师类和学生类,然后写代码测试;最后找到老师类和学生类当中的共性内容,抽取出一个父类,用继承的方式改写代码,并进行测试
看完需求后,我们先简单的说一下思路:
准备
姓名,年龄,教书())
②定义学生类(姓名,年龄,学习())
③定义测试类,写代码测试
/*
老师类
*/
public class Teacher {
private String name;
private int age;
public Teacher() {}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void teach() {
System.out.println("用爱成就每一位学员");
}
}
/*
学生类
*/
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void study() {
System.out.println("好好学习天天向上");
}
}
/*
测试类
*/
public class Demo {
public static void main(String[] args) {
//创建老师类对象进行测试
Teacher t1 = new Teacher();
t1.setName("林青霞");
t1.setAge(30);
System.out.println(t1.getName() + "," + t1.getAge());
t1.teach();
Teacher t2 = new Teacher("风清扬", 33);
System.out.println(t2.getName() + "," + t2.getAge());
t2.teach();
//学生类的测试,留给大家自己练习
}
}
抽取父类
④共性抽取父类,定义人类(姓名,年龄)
⑤定义老师类,继承人类,并给出自己特有方法:教书()
⑥定义学生类,继承人类,并给出自己特有方法:学习()
⑦定义测试类,写代码测试
/*
人类
*/
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/*
老师类
*/
public class Teacher extends Person {
public Teacher() {
}
public Teacher(String name, int age) {
// this.name = name;
// this.age = age;
super(name, age);
}
public void teach() {
System.out.println("用爱成就每一位学员");
}
}
ackage day01.class06;
/*
学生类
*/
public class Student extends Person {
public Student(){
}
public Student (String name,int age){
super(name,age);
}
public void study(){
System.out.println("好好学习 天天向上");
}
}
/*
测试类
*/
public class PersonDemo {
public static void main(String[] args) {
//创建老师类对象并进行测试
Teacher t1 = new Teacher();
t1.setName("林青霞");
t1.setAge(33);
System.out.println(t1.getName() + "," + t1.getAge());
t1.teach();
Teacher t2 = new Teacher("风清扬", 36);
System.out.println(t2.getName() + "," + t2.getAge());
t2.teach();
//学生对象进行测试
Student s1 = new Student();
s1.setName("小林");
s1.setAge(18);
System.out.println(s1.getName() + "," + s1.getAge());
s1.study();
}
}
1.8.2 项目经理和程序员
需求:请使用继承的思想设计出项目经理类和程序员类,并进行测试。
看完这个需求后,我们首先得知道项目经理和程序员都有哪些属性和行为,这样我们才能够设计这两个类,通过这两个类的共性特性,设计出一个父类。
这里呢,我们给出项目经理和程序员的成员变量和成员方法:
项目经理:
成员变量:工号,姓名,工资,奖金
成员方法:工作
程序员:
成员变量:工号,姓名,工资
成员方法:工作
通过分析,我们可以找到它们的共性内容,设计出一个父类:员工类
员工类:
成员变量:工号,姓名,工资
成员方法:工作
程序员类继承自员工类,没有新的成员需要添加。
而项目经理类继承自员工类,需要添加一个成员变量:奖金。
下面给出实现思路:
思路:
①定义员工类(工号,姓名,工资,工作())
②定义项目经理类,继承自员工类,添加一个新的成员变量奖金
③定义程序员类,不需要添加新的成员
④定义测试类,进行测试
分析完毕后,我们到IDEA中去实现一下:
/*
员工类
*/
public class Employee {
//工号
private String id;
//姓名
private String name;
//薪水
private double salary;
public Employee() {
}
public Employee(String id, String name, double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void work() {
System.out.println("员工需要工作");
}
}
/*
项目经理类
*/
public class Manager extends Employee {
//奖金
private double bonus;
public Manager() {
}
public Manager(String id, String name, double salary, double bonus) {
super(id, name, salary);
this.bonus = bonus;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
@Override
public void work() {
System.out.println("项目经理和客户谈需求");
}
}
/*
程序员类
*/
public class Programmer extends Employee {
public Programmer() {
}
public Programmer(String id, String name, double salary) {
super(id, name, salary);
}
@Override
public void work() {
System.out.println("程序员根据需求编写代码");
}
}
/*
测试类
*/
public class EmployeeDemo {
public static void main(String[] args) {
//创建项目经理类对象,并进行测试
Manager m1 = new Manager();
m1.setId("itheima001");
m1.setName("林青霞");
m1.setSalary(10000.00);
m1.setBonus(20000.00);
System.out.println(m1.getId() + "," + m1.getName() + "," + m1.getSalary() + "," + m1.getBonus());
Manager m2 = new Manager("itheima001", "林青霞", 10000.00, 20000.00);
System.out.println(m2.getId() + "," + m2.getName() + "," + m2.getSalary() + "," + m2.getBonus());
System.out.println("-------------------------------");
//创建程序员类对象,并进行测试
Programmer p1 = new Programmer();
p1.setId("itheima520");
p1.setName("风清扬");
p1.setSalary(20000.00);
System.out.println(p1.getId() + "," + p1.getName() + "," + p1.getSalary());
Programmer p2 = new Programmer("itheima520", "风清扬", 20000.00);
System.out.println(p2.getId() + "," + p2.getName() + "," + p2.getSalary());
}
}
m1.setName(“林青霞”);
m1.setSalary(10000.00);
m1.setBonus(20000.00);
System.out.println(m1.getId() + “,” + m1.getName() + “,” + m1.getSalary() + “,” + m1.getBonus());
Manager m2 = new Manager("itheima001", "林青霞", 10000.00, 20000.00);
System.out.println(m2.getId() + "," + m2.getName() + "," + m2.getSalary() + "," + m2.getBonus());
System.out.println("-------------------------------");
//创建程序员类对象,并进行测试
Programmer p1 = new Programmer();
p1.setId("itheima520");
p1.setName("风清扬");
p1.setSalary(20000.00);
System.out.println(p1.getId() + "," + p1.getName() + "," + p1.getSalary());
Programmer p2 = new Programmer("itheima520", "风清扬", 20000.00);
System.out.println(p2.getId() + "," + p2.getName() + "," + p2.getSalary());
}
}