2017年3月29号 星期三 空气质量:中度雾霾~重度雾霾
内容:多态,接口,多态的一道面试题
一、多态(文档讲解)
* 多态:
* 同一个操作,由于条件的不同,产生不同的结果!
* 同一个引用类型,使用不同的实例而执行不同的结果!
*
* 多态的两种形式:
* 01.编译时的多态(方法重载)
* feed(Dog dog)
* feed(Cat cat)
* feed(Penguin penguin)
* 02.运行时的多态
* 程序在运行期间,根据不同的参数类型,从而执行不同的对象方法!
*
* 多态存在的必要条件:
* 01.有继承!
* 02.有重写!
* 03.父类的引用指向了子类的对象!
* 给小宠物喂食
01.父类对象作为参数
master.feed(dog); 父类的引用指向了子类的对象!
master.feed(penguin);
*/
/**
* 出售宠物
* 02.返回值是父类类型, 可以用子类类型接收
*Pet pet=new Dog();
* 小狗是宠物--->OK!
* dog = master.salePet(dog);
* 宠物是小狗???--->
* dog = (Dog) master.salePet(dog);--->正确
* 向下转型:
* 把父类类型 转换成其对应的子类类型!
* dog = (Dog) master.salePet(dog);
二、多态(图示)
三、多态Demo
1、老师代码:
1)狗狗实体类:
package cn.bdqn.bean;
/**
*狗狗的实体类
*/
public class Dog extends Pet {
private String strain; // 品种
// 无参构造方法
public Dog() {
}
// 带参构造函数
public Dog(String name, String strain, int health, int love) {
this.strain = strain;
}
public void showInfo() {
super.showInfo(); // 调用父类的方法
System.out.println("品种是:" + this.strain);
}
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
/**
* 吃食的方法
*/
public void eat() {
System.out.println("小狗狗在吃骨头");
}
// 出售宠物
@Override
public Dog salePet() {
System.out.println("小狗狗被卖掉了!");
return this;
}
// 小狗玩耍的方法
public void dogPlay() {
System.out.println("小狗玩耍的方法");
}
}
2)企鹅实体类:
package cn.bdqn.bean;
/**
*企鹅的实体类
*/
public class Penguin extends Pet {
public String sex; // 性别
// 带参构造
public Penguin(String name, int health, int love, String sex) {
System.out.println("Penguin的带参构造");
this.sex = sex;
}
/**
* 重写父类的方法
*/
@Override
public void showInfo() {
super.showInfo();
System.out.println("性别是:" + sex);
}
// 无参构造
public Penguin() {
}
/**
* 吃食的方法
*/
public void eat() {
System.out.println("企鹅在吃鱼");
}
// 出售的方法
@Override
public Penguin salePet() {
System.out.println("企鹅被卖掉了!");
return this;
}
// 企鹅玩耍的方法
public void penguinPlay() {
System.out.println("企鹅玩耍的方法");
}
}
3)宠物类(父类):
package cn.bdqn.bean;
//宠物类(父类)
public abstract class Pet {
// 成员变量 子类 共有的属性
private String name; // 姓名
private int health;// 健康值
private int love;// 亲密度
// 父类的无参构造
public Pet() {
}
// 带参构造
public Pet(String name, int health, int love) {
this.name = name;
this.health = health;
this.love = love;
}
/**
* 输出宠物的信息 所有宠物 共享的!
*/
public void showInfo() {
System.out.println("姓名:" + this.name);
System.out.println("健康值:" + this.health);
System.out.println("亲密度:" + this.love);
}
// 对应的set和get方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
/**
* 有必要写方法体吗?
* 因为每个宠物的吃饭方法都是不一致的!
*/
public abstract void eat();
// 宠物被卖掉的方法
public abstract Pet salePet();
}
4)所有宠物的主人类:
package cn.bdqn.bean;
/**
* 所有宠物的主人类
*/
public class Master {
/**
* 主人喂养着两个宠物
* 01.给小狗狗喂食
public void feed(Dog dog) {
dog.eat();
}
02.给企鹅喂食
public void feed(Penguin penguin) {
penguin.eat();
}
主人可以养许多的宠物,每个宠物吃食的方法都是不一样的!
那么我们就必须在这个主人类中书写N个喂食的方法!
这样很麻烦!
怎么解决这个问题?
*/
/**
* 多态的实现:
* 01.父类对象作为参数
*/
public void feed(Pet pet) {
pet.eat();
}
/**
* 02.返回值是父类类型
* 主人不开心,卖宠物!
* 传过来一个 宠物,之后卖掉
*/
public Pet salePet(Pet pet) {
pet.salePet();
return pet;
}
/**
* 模拟主人与宠物进行玩耍
* 01.先在我们的pet中创建公共的play方法
* 02.两个子类中去重写
*
* 如果子类中的方法名不一致了?子类中有特有的方法?
* 什么是特有的方法? 父类中没有的!
* 就像根据传入实例的不同,调用不同的对象方法!
* 这时候我们怎么来区分是哪个宠物?
*/
public void play(Pet pet) {
if (pet instanceof Dog) {
// 需要把pet向下转型为Dog
Dog dog = (Dog) pet;
dog.dogPlay();
}
if (pet instanceof Penguin) {
// 需要把pet向下转型为Penguin
Penguin penguin = (Penguin) pet;
penguin.penguinPlay();
}
}
}
5)测试类:
package cn.bdqn.test;
//测试类
import cn.bdqn.bean.Dog;
import cn.bdqn.bean.Master;
import cn.bdqn.bean.Penguin;
/**
*
* 多态:
* 同一个操作,由于条件的不同,产生不同的结果!
* 同一个引用类型,使用不同的实例而执行不同的结果!
*
* 多态的两种形式:
* 01.编译时的多态(方法重载)
* feed(Dog dog)
* feed(Cat cat)
* feed(Penguin penguin)
* 02.运行时的多态
* 程序在运行期间,根据不同的参数类型,从而执行不同的对象方法!
*
* 多态存在的必要条件:
* 01.有继承!
* 02.有重写!
* 03.父类的引用指向了子类的对象!
*/
public class PetTest {
public static void main(String[] args) {
// 实现主人给两个宠物喂食
Dog dog = new Dog();
Penguin penguin = new Penguin();
// 创建主人实例
Master master = new Master();
/**
* 给小宠物喂食
01.父类对象作为参数
master.feed(dog); 父类的引用指向了子类的对象!
master.feed(penguin);
*/
/**
* 出售宠物
* 02.返回值是父类类型, 可以用子类类型接收
* 小狗是宠物
* dog = master.salePet(dog);
* 宠物是小狗???
dog = (Dog) master.salePet(dog);
* 向下转型
* 把父类类型 转换成其对应的子类类型!
* dog = (Dog) master.salePet(dog);
*/
// 玩耍的方法
master.play(dog);
}
}
四、多态的一道面试题Demo(难点,梳理清楚)
老师代码:
1、类A:
package exam;
public class A {
// 现在这两个方法是 重载
public String show(D d) {
return "A and D";
}
public String show(A a) {
return "A and A";
}
}
2、类B:
package exam;
public class B extends A { // 继承了 A
// 现在这两个方法是 重载
public String show(B b) {
return "B and B";
}
// 重写了A的方法
public String show(A a) {
return "B and A";
}
}
3、类C:
package exam;
public class C extends B {
}
4、类D:
package exam;
public class D extends B {
}
5、测试类:
package exam;
public class TestABCD {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B(); // 父类的引用 指向了子类的对象
B b = new B();
C c = new C();
D d = new D();
// A and A System.out.println(a1.show(b));
// A and A System.out.println(a1.show(c));
// A and D System.out.println(a1.show(d));
// B and A System.out.println(a2.show(b)); 子类中有对应的方法 执行子类重写之后的方法
// B and A System.out.println(a2.show(c)); 子类中没有对应的方法 执行父类的方法
// A and D System.out.println(a2.show(d));
// B and B System.out.println(b.show(b));
// B and B System.out.println(b.show(c));//子类和父类都没有完全对应c的方法,先继承到父类b传参(自己理解)
// A and D System.out.println(b.show(d)); //子类中没有对应的方法, 直接去 父类中查询
}
}
五、接口(文档讲解):
* java中不支持 多继承!
* 接口来解决这个问题!
*
* interface:接口! 本身就是一个抽象类!
* 接口中就是提供了 某种能力,但是它不关心 能力的实现!
* 接口的特点:
* 01.接口中所有的方法都是 public abstract修饰的!不允许出现方法体
* 02.接口的实现类 必须去实现接口中所有的方法,除非实现类是抽象类或者接口!
* 03.接口中所有的属性都是 final static修饰的静态常量,必须赋予初始值!
* 04.接口可以实现接口,只不过实现的方式是用extends
* Fly extends Fly2, Fly3 =====》多实现 并不是多继承!
* 05.接口不能实例化! 也不能有构造方法!
*
* 常用的接口方式:
* 01.接口什么都不定义!!!
* 02.接口中定义了 很多 静态常量!
* 03.接口中定义了很多 方法!
*
*
* 对象与类的关系 是 is a
* 对象与接口的关系 是 has a
六、接口(图示)
七、接口Demo01(小鸟飞行)
老师代码:
1、Bird类继承了宠物类 实现了 Fly接口中的功能:
package cn.bdqn.bean;
import cn.bdqn.dao.Fly;
/**
*Bird继承了宠物类 实现了 Fly接口中的功能!
*/
public class Bird extends Pet implements Fly {
@Override
public void eat() {
System.out.println("小鸟在吃虫子");
}
// 实现了 Fly接口中的功能!
@Override
public void fly() {
System.out.println("小鸟在飞行");
}
}
2、宠物类(父类):
package cn.bdqn.bean;
//宠物类(父类)
public abstract class Pet {
// 成员变量 子类 共有的属性
private String name; // 姓名
private int health;// 健康值
private int love;// 亲密度
// 父类的无参构造
public Pet() {
}
// 带参构造
public Pet(String name, int health, int love) {
this.name = name;
this.health = health;
this.love = love;
}
/**
* 输出宠物的信息 所有宠物 共享的!
*/
public void showInfo() {
System.out.println("姓名:" + this.name);
System.out.println("健康值:" + this.health);
System.out.println("亲密度:" + this.love);
}
// 对应的set和get方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public abstract void eat();
}
3、接口fly:
package cn.bdqn.dao;
/**
*
* java中不支持 多继承!
* 接口来解决这个问题!
*
* interface:接口! 本身就是一个抽象类!
* 接口中就是提供了 某种能力,但是它不关心 能力的实现!
* 接口的特点:
* 01.接口中所有的方法都是 public abstract修饰的!不允许出现方法体
* 02.接口的实现类 必须去实现接口中所有的方法,除非实现类是抽象类或者接口!
* 03.接口中所有的属性都是 final static修饰的静态常量,必须赋予初始值!
* 04.接口可以实现接口,只不过实现的方式是用extends
* Fly extends Fly2, Fly3 =====》多实现 并不是多继承!
* 05.接口不能实例化! 也不能有构造方法!
*
* 常用的接口方式:
* 01.接口什么都不定义!!!
* 02.接口中定义了 很多 静态常量!
* 03.接口中定义了很多 方法!
*
*
* 对象与类的关系 是 is a
* 对象与接口的关系 是 has a
*
*/
// public interface Fly extends Fly2, Fly3 {
public interface Fly {
/**
* 能力
*/
void fly();
}
4、接口fly2:
package cn.bdqn.dao;
public interface Fly2 {
void fly2();
}
5、接口fly3:
package cn.bdqn.dao;
public interface Fly3 {
void fly3();
}
6、测试类:
package cn.bdqn.test;
import cn.bdqn.bean.Bird;
public class BirdTest {
public static void main(String[] args) {
Bird bird = new Bird();
bird.eat();
bird.fly(); // 功能
}
}
八、接口Demo02(防盗门)
老师代码:
1、门的抽象类(开门,关门两个方法):
package cn.bdqn.bean;
/**
* 门
* 不同的门 开门关门的 方式不同
* 我们不能把功能写死
*
* 门 是抽象类
* 卷帘门
* 木门
* 铁门
* 玻璃门
*/
public abstract class Door {
// 开门
public abstract void open();
// 关门
public abstract void close();
}
2、防盗的接口(上锁,开锁两个方法):
package cn.bdqn.dao;
/**
* 接口只是提供了 某些功能
*
* 防盗门 具有防盗的功能
* 防盗窗 具有防盗的功能
*
* 上锁和 开锁
*/
public interface LockInterface {
// 上锁
void lockUp();
// 开锁
void lockDown();
}
3、防盗门类(继承门,实现防盗接口):
package cn.bdqn.bean;
import cn.bdqn.dao.LockInterface;
/**
*
*防盗门 首先是一个门 然后具有防盗的功能
*/
public class PanDoor extends Door implements LockInterface {
@Override
public void lockUp() {
System.out.println("门被锁上了");
}
@Override
public void lockDown() {
System.out.println("锁被打开了");
}
@Override
public void open() {
System.out.println("门被打开了");
}
@Override
public void close() {
System.out.println("门被关上了");
}
}
4、测试类:
package cn.bdqn.test;
import cn.bdqn.bean.PanDoor;
public class TestDoor {
public static void main(String[] args) {
PanDoor door = new PanDoor();
door.lockDown();
door.open();
door.close();
door.lockUp();
}
}
九、作业
1、视频至少看完高级第一节(集合),最好能看完实用类
2、租赁汽车项目下次课前交到局域网
3、做题
十、老师辛苦了!