前言
b站java课程学习笔记整理。
b站视频: 黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程
169. 多态
指的是同一个对象在不同情况下表现出来的不同形态。
我们可以说Kitty是猫的一种,也可以说Kitty是动物的一种。
多态的前提和实现
- 有继承/实现关系
- 有方法的重写
- 有父类引用指向子类的对象(
动物 animal = new 猫()
)
1 2 3 4 5 6 7 8
| package 多态;
public class Animal { public void eat(){ System.out.println("动物吃东西"); } }
|
1 2 3 4 5 6 7 8 9
| package 多态;
public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } }
|
1 2 3 4 5 6 7 8 9
| package 多态;
public class test { public static void main(String[] args) { Animal A = new Cat(); A.eat(); } }
|
总结: 多态就是父类 对象=new 子类;
170. 多态中的成员访问特点
- 通过多态的形式访问成员变量,编译和运行要看左边。
- 通过多态的形式访问成员方法,编译看左边(父类中要有这个方法),运行看右边(运行的是子类中重写的方法)。
171. 多态的好处和弊端
代码:
1 2 3 4 5 6 7 8
| package 多态;
public class Animal { public void eat(){ System.out.println("动物吃东西"); } }
|
1 2 3 4 5 6 7 8 9
| package 多态;
public class Cat extends Animal{ @Override public void eat() { System.out.println("猫吃鱼"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| package 多态;
public class Dog extends Animal{ @Override public void eat(){ System.out.println("狗吃肉"); } public void security(){ System.out.println("狗能看门"); } }
|
1 2 3 4 5 6 7 8
| package 多态;
public class AnimalOperator { public void operate(Animal a){ a.eat(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package 多态;
public class test { public static void main(String[] args) { Cat c = new Cat(); c.eat(); Dog d = new Dog(); d.eat();
AnimalOperator ao = new AnimalOperator(); ao.operate(c); ao.operate(d);
} }
|
172. 多态中的转型
转型可以实现使用子类中的特有功能。转型分为向上转型(父类引用指向子类对象)和向下转型(父类引用强转为子类对象)。
代码:
1 2 3 4 5 6 7 8
| package 多态强转;
public class Animal { public void eat(){ System.out.println("动物吃东西"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| package 多态强转;
public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } public void play(){ System.out.println("猫玩玩具"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package 多态强转;
public class test { public static void main(String[] args) { Animal a = new Cat(); a.eat();
Cat c = (Cat)a; c.eat(); c.play();
} }
|
173. 多态转型的内存图
关键就是向下转型时要做一步判断。
174. 猫和狗
案例:猫和狗,需求使用多态的思想实现猫和狗。
- 定义动物类,包括成员变量(名字,年龄)、成员方法(getset,吃饭())、构造方法(无参、带参)。
- 定义猫类,包括成员方法(重写吃饭())、构造方法(无参、带参)。
- 定义狗类,包括成员方法(重写吃饭())、构造方法(无参、带参)。
- 定义测试类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package 猫与狗多态;
public class Animal { private String name; private String age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getAge() { return age; }
public void setAge(String age) { this.age = age; }
public Animal() { }
public Animal(String name, String age) { this.name = name; this.age = age; }
public void eat(){ System.out.println("动物吃饭"); }
public void show() { System.out.println(name + "," + age); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package 猫与狗多态;
public class Cat extends Animal{ public Cat(){}
public Cat(String name, String age){ super(name, age); }
@Override public void eat(){ System.out.println("猫吃鱼"); }
public void play(){ System.out.println("猫玩玩具"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package 猫与狗多态;
public class Dog extends Animal{ public Dog(){}
public Dog(String name, String age){ super(name, age); }
@Override public void eat(){ System.out.println("狗吃肉"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package 猫与狗多态;
public class Test { public static void main(String[] args) { Animal a = new Cat(); a.setAge("21"); a.setName("加菲"); a.show(); a.eat();
System.out.println("----------------------------");
Animal b = new Cat("加菲", "10"); b.show(); b.eat(); Cat c = (Cat) b; c.play();
System.out.println("----------------------------");
Animal d = new Dog("加菲", "10"); d.show(); d.eat();
} }
|
总结:继承版猫与狗时提取共性,多态版猫和狗是对一个大类的重写整合。
175. 抽象类
动物不应该作为一个可以被创建对象的类!因为动物就是一个抽象的概念!
一个没有方法体的方法被定义为抽象方法,类被定义为抽象类。
176. 抽象类特点
- 抽象类和抽象方法要用
abstract
关键字来修饰。
- 抽象类里是可以有非抽象方法的。但是也可以没有抽象方法(但是没什么意义)。
- 类里有抽象方法,类一定是抽象类。
- 抽象类无法常规创建对象。抽象类会参照多态的方式创建对象。即先定义一个类继承,然后正常重写方法。
- 抽象类的子类要么重写继承所有的抽象方法,要么定义为抽象子类。
177. 抽象类的成员特点
178. 猫与狗(抽象类版)
- 定义动物类,姓名年龄,无参带参构造,getset方法,抽象eat()方法。
- 定义Cat类,继承,无参带参,重写吃饭
- 定义Dog类,继承,无参带参,重写吃饭
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package 猫和狗抽象类;
public abstract class Animal { private String name; private String age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getAge() { return age; }
public void setAge(String age) { this.age = age; }
public Animal() { }
;
public Animal(String name, String age) { this.age = age; this.name = name; }
;
public abstract void eat();
public void show() { System.out.println(name + "," + age); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package 猫和狗抽象类;
public class Cat extends Animal { public Cat() { }
public Cat(String name, String age) { super(name, age); }
@Override public void eat() { System.out.println("猫吃鱼"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package 猫和狗抽象类;
public class Dog extends Animal { public Dog() { }
public Dog(String name, String age) { super(name, age); }
@Override public void eat() { System.out.println("狗吃肉"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package 猫和狗抽象类;
public class test { public static void main(String[] args) { Animal a = new Cat(); a.setAge("11"); a.setName("Kitty"); a.eat(); a.show();
Animal b = new Dog("Dogge","19"); b.eat(); b.show(); } }
|
总结:就是在猫和狗多态版的基础上,去除了Animal
可以实体化的特性,将Animal
变成了一个抽象的“定义”。
179. 接口
接口是一种公共的规范标准。只要符合标准,大家都可以用。Java中的接口更多的体现在对行为的抽象。
180. 接口的特点
- 接口关键字用
interface
修饰。
- 类实现接口用
implements
表示。
- 接口不能实例化,要参照多态的方式使用子类实例化。
- 多态的形式:具体类多态,抽象类多态,接口类多态。
- 接口的实现类:要么重写抽象方法,要么是抽象类。
181. 接口的成员特点
- 接口中的成员变量默认被
public static final
修饰。所以接口中默认都是常量。
- 接口里没有构造方法(所有的子类默认访问的都是
object
无参构造)
- 接口里不能有非抽象成员方法。
- 在接口里的方法默认带了
public abstract
前缀。
182. 猫和狗接口版
案例:对猫和狗训练,实现跳高功能。
- 定义接口,跳高。
- 定义动物类,姓名年龄,无参带参构造,getset方法,抽象eat()方法。
- 定义Cat类,继承,无参带参,重写吃饭,跳高
- 定义Dog类,继承,无参带参,重写吃饭,跳高
代码只写了个猫的,以猫为例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package 猫和狗接口;
public abstract class Animal { private String name; private String age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getAge() { return age; }
public void setAge(String age) { this.age = age; }
public Animal(String name, String age) { this.name = name; this.age = age; }
public Animal() {
}
public abstract void eat();
public void show() { System.out.println(name + "," + age); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package 猫和狗接口;
public class Cat extends Animal implements Jumpping{ public Cat(){} public Cat(String name,String age){ super(name, age); };
@Override public void eat() { System.out.println("猫吃鱼"); }
@Override public void jump() { System.out.println("猫跳高"); } }
|
1 2 3 4 5 6
| package 猫和狗接口;
public interface Jumpping { public abstract void jump(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package 猫和狗接口;
public class test { public static void main(String[] args) { Animal a = new Cat("Kitty","23"); a.show(); a.eat(); ((Cat)a).jump();
Jumpping j = new Cat("Doppy","21"); j.jump();
Cat c = new Cat("James","18"); c.show(); c.eat(); c.jump(); }
}
|
183. 类和接口的关系
- 类和类的关系:继承关系,只能一对一继承,但是可以多层继承。
- 类和接口的关系: 可以实现多个接口。甚至可以在继承一个类的时候实现接口。(
extends x implements inter1,inter2,inter3
)
- 接口与接口的关系:可以单继承,也可以多继承。 (
extends x,y,z
)
184. 抽象类和接口的区别
将类所具有的本身的功能设计为抽象类,将一些外部功能设计为接口。
抽象类是对事物的抽象,接口是对行为的抽象。
185.运动员和教练:案例分析
现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练,跟乒乓球相关的需要学习英语。试着做出代码设计。
抽象类:人类:运动员、教练。
子类:乒乓球教练、篮球教练。
接口:学英语。
最后写测试类测试。
注意:谁不抽象,谁重写。
1 2 3 4 5 6
| package 运动员与教练接口;
public interface English { public abstract void speakEnglish(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package 运动员与教练接口;
public abstract class Human { private String name; private String age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getAge() { return age; }
public void setAge(String age) { this.age = age; }
public Human(String name, String age) { this.name = name; this.age = age; }
public Human(){}
public abstract void eat();
public void show(){ System.out.println("姓名"+name+"年龄"+age); } }
|
1 2 3 4 5 6 7 8 9 10 11
| package 运动员与教练接口;
public abstract class Coach extends Human { Coach(){} Coach(String name, String age){ super(name, age); }
public abstract void teach(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| package 运动员与教练接口;
public abstract class Sportsman extends Human { public Sportsman() { }
public Sportsman(String name, String age) { super(name, age); }
public abstract void study(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package 运动员与教练接口;
public class BBCoach extends Coach{ public BBCoach() { }
public BBCoach(String name, String age) { super(name, age); }
@Override public void eat() { System.out.println("篮球教练吃饭"); }
@Override public void teach() { System.out.println("篮球教练教篮球"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package 运动员与教练接口;
public class BBSportsman extends Sportsman { public BBSportsman() { }
public BBSportsman(String name, String age) { super(name, age); }
@Override public void eat() { System.out.println("篮球运动员吃饭"); }
@Override public void study() { System.out.println("篮球运动员学习打篮球"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package 运动员与教练接口;
public class TTCoach extends Coach implements English{ public TTCoach() { }
public TTCoach(String name, String age) { super(name, age); }
@Override public void eat() { System.out.println("乒乓球教练吃饭"); }
@Override public void teach() { System.out.println("乒乓球教练教乒乓球"); }
@Override public void speakEnglish() { System.out.println("乒乓球教练需要学习英语"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package 运动员与教练接口;
public class TTSportsman extends Sportsman implements English{ public TTSportsman() { }
public TTSportsman(String name, String age) { super(name, age); }
@Override public void eat() { System.out.println("乒乓球运动员吃饭"); }
@Override public void study() { System.out.println("乒乓球运动员学乒乓球");
}
@Override public void speakEnglish() { System.out.println("乒乓球运动员学英语"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package 运动员与教练接口;
public class test { public static void main(String[] args) { BBSportsman bbs = new BBSportsman("James","21"); bbs.show(); bbs.eat(); bbs.study(); System.out.println("----------------------------"); TTSportsman tts = new TTSportsman(); tts.setAge("19"); tts.setName("Long Ma"); tts.show(); tts.eat(); tts.study(); tts.speakEnglish(); System.out.println("----------------------------"); BBCoach bbc = new BBCoach("Popovich","80"); bbc.show(); bbc.eat(); bbc.teach(); System.out.println("----------------------------"); TTCoach ttc = new TTCoach("Guoliang Liu","45"); ttc.show(); ttc.eat(); ttc.teach(); ttc.speakEnglish(); } }
|