今日学习:
1.多态(动态绑定机制):定义;成员访问特点;好处和弊端;向上转型和向下转型;多态内存图
2.抽象类:定义;成员特点
3.接口:定义;成员特点类与类;类与接口;接口与接口的关系;抽象类与接口的区别
多态的定义及其代码体现
1.多态定义:某一个事物,在不同时刻表现出来的不同状态。
举例:
Cat c=new Cat() ; Animal a=new Cat();
猫可以是猫的类型:猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物:动物 d = new 猫();
2.多态前提
(1).要有继承关系;
(2).要有方法重写。 其实没有也是可以的,但是如果没有这个就没有意义;
(3).要有父类引用指向子类对象:父 f = new 子();。
多态中的成员访问特点
1.成员变量:编译看左边,运行看左边。
2.构造方法:创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
3.成员方法:编译看左边,运行看右边。
4.静态方法:编译看左边,运行看左边。(静态和类相关,算不上重写,所以,访问还是左边的)
多态的好处与弊端及解决方法
1.多态的好处:提高了代码的维护性(继承保证)和扩展性(由多态保证)。
2.多态的弊端:多态的形式不能直接调用子类特有的方法。
3.解决方法:把父类的引用强制转换为子类的引用。(向下转型)。
孔子装爹(代码)
public class MyTest {
public static void main(String[] args) {
/*
孔子爹,是一个知名的Java讲师,很多学员慕名前来,学Java 张三就去孔子的家里去请孔子爹去他家里讲Java
家里就剩孔子一个人,在家玩游戏,这时李四也来到了孔子家里,去请孔子爹,孔子一看来生意了,不想失去这个学员
就乔装打扮一番,扮成他爹的模样去给李四讲课去,孔子讲的就是论语。
将完之后,孔子说装爹太累了,想要做回自己,那样就可以愉快的玩游戏了。
*/
//多态:向上转型,父类引用指向子类对象
孔子爹 k爹 = new 孔子();
System.out.println(k爹.age);
k爹.teach();
//做回他自己,向下转型
孔子 kz = (孔子) k爹;
System.out.println(kz.age);
kz.playGame();
}
}
class 孔子爹 {
int age = 60;
public void teach() {
System.out.printf("讲授Java");
}
}
class 孔子 extends 孔子爹 {
int age = 30;
@Override
public void teach() {
System.out.println("讲授论语");
}
public void playGame() {
System.out.println("玩游戏");
}
}
多态的内存图解
猫狗案例多态版
//测试类
public class MyTest {
public static void main(String[] args) {
Animal an = new Cat();
an.eat();
Cat cat = (Cat) an;
cat.catchMouse();
an = new Dog();
Dog dog = (Dog) an;
an.eat();
dog.lookDoor();
}
}
//动物类
class Animal {
public void eat() {
System.out.println("吃饭");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse() {
System.out.println("猫抓老鼠");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void lookDoor() {
System.out.println("狗看门");
}
}
多态中的题目分析题
1.看下面程序是否有问题,如果没有,说出结果
class Fu {
public void show() {
System.out.println("fu show");
}
}
class Zi extends Fu {
public void show() {
System.out.println("zi show");
}
public void method() {
System.out.println("zi method");
}
}
class DuoTaiTest3 {
public static void main(String[] args){
Fu f = new Zi();
f.method(); //报错 ,不能直接调用子类特有的方法
f.show();
}
}
输出结果:
zi show
2.看下面程序是否有问题,如果没有,说出结果
class A {
public void show() {
show2();
}
public void show2() {
System.out.println("我");
}
}
class B extends A {
public void show2() {
System.out.println("爱");
}
}
class C extends B {
public void show() {
super.show();
}
public void show2() {
System.out.println("你");
}
}
public class DuoTaiTest4 {
public static void main(String[] args) {
A a = new B();
a.show();
B b = new C();
b.show();
输出结果:
爱
你
抽象类的定义及其特点
1.抽象类定义
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。
2.抽象类特点
(1).抽象类和抽象方法必须用abstract关键字修饰
抽象类格式: abstract class 类名 {}
抽象方法格式: public abstract void eat();
(2).抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
(3).抽象类中可以有构造方法,抽象类不能进行实例化,那么要构造方法有什么作用呢?
用于子类访问父类数据时的初始化
(4).抽象类不能直接实例化那么,抽象类如何实例化呢?
按照多态的方式,由具体的子类实例化。
(5).抽象类的子类
抽象类或者重写抽象类中的所有抽象方法
抽象类的成员特点
1.抽象类的成员特点
(1).成员变量:既可以是变量,也可以是常量。
(2).构造方法:有。用于子类访问父类数据的初始化。
(3).成员方法:既可以是抽象的,也可以是非抽象的。
2.抽象类的成员方法特性:
(1).抽象方法:强制要求子类做的事情。
(2).非抽象方法:子类继承的事情,提高代码复用性。
抽象类练习:老师案例
/*具体事物:基础班老师,就业班老师
共性:姓名,年龄,讲课。
*/
//测试类
public class Mytest {
public static void main(String[] args) {
BaseTeacher baseTeacher = new BaseTeacher();
baseTeacher.setName("杨老师");
baseTeacher.setAge(18);
System.out.println(baseTeacher.getName());
System.out.println(baseTeacher.getAge());
baseTeacher.teach();
WorkTeacher workTeacher = new WorkTeacher();
workTeacher.setName("王老师");
workTeacher.setAge(18);
System.out.println(workTeacher.getName());
System.out.println(workTeacher.getAge());
workTeacher.teach();
}
}
//老师类
abstract class Teacher{
private String name;
private int 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 abstract void teach();
}
class BaseTeacher extends Teacher{
@Override
public void teach() {
System.out.println("讲授基础知识");
}
}
class WorkTeacher extends Teacher{
@Override
public void teach() {
System.out.println("讲授面试技巧");
}
}
抽象类练习:员工案例
//测试类
public class Mytest {
public static void main(String[] args) {
Coder coder = new Coder();
coder.setName("项羽");
coder.setIdcard("007");
coder.setSalary(8000);
System.out.println(coder.getName());
System.out.println(coder.getIdcard());
System.out.println(coder.getSalary());
coder.work();
Manager manager = new Manager();
manager.setName("虞姬");
manager.setIdcard("008");
manager.setSalary(9000);
manager.setBonus(3000);
System.out.println(manager.getName());
System.out.println(manager.getIdcard());
System.out.println(manager.getSalary());
System.out.println(manager.getBonus());
manager.work();
}
}
//员工
abstract class Employee{
private String name;
private String idcard;
private double salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdcard() {
return idcard;
}
public void setIdcard(String idcard) {
this.idcard = idcard;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public abstract void work();
}
//程序员
class Coder extends Employee{
@Override
public void work() {
System.out.println("我的姓名是:"+this.getName() + ",我的工号是:"+this.getIdcard() + ",我的工资是:"
+this.getSalary() + ",我的工作是敲代码");
}
}
//项目经理
class Manager extends Employee{
private int bonus;
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
@Override
public void work() {
System.out.println("我的姓名是:"+this.getName() + ",我的工号是:"+this.getIdcard() + ",我的工资是:"
+this.getSalary() + ",我的奖金是:" +this.getBonus() + ",我的工作是项目布置");
}
}
抽象类中的面试题
1.面试题1
一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
答案: 可以。不能创建对象。
2.面试题2
abstract不能和哪些关键字共存?
private 冲突
final 冲突
static 不能共存 无意义
接口的定义及其特点
1.接口定义:为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。
2.接口特点
(1).接口用关键字interface表示 格式: interface 接口名 {}
(2).类实现接口用implements表示 格式: class 类名 implements 接口名 {}
(3).接口如何实例化呢? 按照多态的方式来实例化。
(4).接口的子类
1).可以是抽象类。但是意义不大。
2).可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
接口的成员特点
1.成员变量;只能是常量,并且是静态的。
默认修饰符:public static final
建议:自己手动给出。
2.构造方法:接口没有构造方法。
3.成员方法:只能是抽象方法。
默认修饰符:public abstract
建议:自己手动给出。
类与类,类与接口,接口与接口的关系
1.类与类:继承关系,只能单继承,可以多层继承;
2.类与接口:实现关系,可以单实现,也可以多实现,并且还可以在继承一个类的同时实现多个接口;
3.接口与接口:继承关系,可以单继承,也可以多继承。
抽象类和接口的区别
1.成员区别
(1).抽象类:
成员变量:可以变量,也可以常量
构造方法:有
成员方法:可以抽象,也可以非抽象
(2).接口:
成员变量:只可以常量
成员方法:只可以抽象
2.关系区别
(1).类与类:继承,单继承
(2).类与接口:实现,单实现,多实现
(3).接口与接口:继承,单继承,多继承
3.设计理念区别
抽象类 被继承体现的是:”is a”的关系。 抽象类中定义的是该继承体系的共性功能。
接口 被实现体现的是:”like a”的关系。 接口中定义的是该继承体系的扩展功能。
注意:JDK1.8之后在接口中提供了用default修饰的方法,可以给出功能的具体实现,子类可以继承下去用
JDK1.8之后在接口中也可以定义静态方法
猫狗案例加入跳高功能分析及其代码实现
//测试类
public class Mytest {
public static void main(String[] args) {
/*布偶 bo = new 布偶();
bo.name = "布偶";
bo.age = 2;
System.out.println(bo.name);
System.out.println(bo.age);
bo.eat();
bo.sleep();
JumpInterface jumpInterface = bo;
jumpInterface.jump();
美短 md = new 美短();
md.name = "美短";
md.age = 3;
System.out.println(md.name);
System.out.println(md.age);
md.eat();
md.sleep();
System.out.println("=====================");
*/
二哈 eh = new 二哈();
eh.name = "二哈";
eh.age = 2;
System.out.println(eh.name);
System.out.println(eh.age);
eh.eat();
eh.sleep();
JumpInterface jumpInterface = eh;
jumpInterface.jump();
柯基 kj = new 柯基();
kj.name = "柯基";
kj.age = 3;
System.out.println(kj.name);
System.out.println(kj.age);
kj.eat();
kj.sleep();
}
}
//接口
public interface JumpInterface {
void jump();
}
//动物类
abstract class Animal {
String name;
int age;
public abstract void eat();
public abstract void sleep();
}
//狗类
class Dog extends Animal{
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void sleep() {
System.out.println("睡觉");
}
}
//猫类
class Cat extends Animal{
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void sleep() {
System.out.println("睡觉");
}
}
//布偶与美短
class 布偶 extends Cat implements JumpInterface{
@Override
public void eat() {
System.out.println("布偶吃的鱼罐头");
}
@Override
public void sleep() {
System.out.println("布偶睡沙发");
}
@Override
public void jump() {
System.out.println("布偶学会了跳高");
}
}
public class 美短 extends Cat implements JumpInterface {
@Override
public void eat() {
System.out.println("美短吃的鱼罐头");
}
@Override
public void sleep() {
System.out.println("美短睡沙发");
}
@Override
public void jump() {
System.out.println("美短学不会跳高");
}
}
//二哈与柯基
class 二哈 extends Dog implements JumpInterface{
@Override
public void eat() {
System.out.println("二哈吃的是高级狗粮");
}
@Override
public void sleep() {
System.out.println("二哈睡的是床");
}
@Override
public void jump() {
System.out.println("二哈 学会了跳高");
}
}
public class 柯基 extends Dog implements JumpInterface{
@Override
public void eat() {
System.out.println("柯基吃的是高级狗粮");
}
@Override
public void sleep() {
System.out.println("二哈睡的是床");
}
@Override
public void jump() {
System.out.println("柯基 学不会跳高");
}
}
注意:不论是实现猫类还是狗类,只需将其中一行代码注释即可。