✈【【零基础 快速学Java】韩顺平 零基础30天学会Java】

【传统方法解决】
传统的方法带来的问题:代码的复用性不高,而且不利于代码维护。
解决方案:多态
【举个栗子】
动物类
package com.dingjiaxiong.poly_;
/**
* ClassName: Animal
* date: 2022/9/3 11:14
*
* @author DingJiaxiong
*/
public class Animal {
private String name;
public Animal(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
狗类
package com.dingjiaxiong.poly_;
/**
* ClassName: Dog
* date: 2022/9/3 11:16
*
* @author DingJiaxiong
*/
public class Dog extends Animal{
public Dog(String name) {
super(name);
}
}
猫类
package com.dingjiaxiong.poly_;
/**
* ClassName: Cat
* date: 2022/9/3 11:16
*
* @author DingJiaxiong
*/
public class Cat extends Animal{
public Cat(String name) {
super(name);
}
}
猪类
package com.dingjiaxiong.poly_;
/**
* ClassName: Pig
* date: 2022/9/3 11:21
*
* @author DingJiaxiong
*/
public class Pig extends Animal{
public Pig(String name) {
super(name);
}
}
食物类
package com.dingjiaxiong.poly_;
/**
* ClassName: Food
* date: 2022/9/3 11:15
*
* @author DingJiaxiong
*/
public class Food {
private String name;
public Food(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
骨头类
package com.dingjiaxiong.poly_;
/**
* ClassName: Bone
* date: 2022/9/3 11:16
*
* @author DingJiaxiong
*/
public class Bone extends Food{
public Bone(String name) {
super(name);
}
}
鱼类
package com.dingjiaxiong.poly_;
/**
* ClassName: Fish
* date: 2022/9/3 11:16
*
* @author DingJiaxiong
*/
public class Fish extends Food{
public Fish(String name) {
super(name);
}
}
米饭类
package com.dingjiaxiong.poly_;
/**
* ClassName: Rice
* date: 2022/9/3 11:21
*
* @author DingJiaxiong
*/
public class Rice extends Food {
public Rice(String name) {
super(name);
}
}
主人类
package com.dingjiaxiong.poly_;
/**
* ClassName: Master
* date: 2022/9/3 11:17
*
* @author DingJiaxiong
*/
public class Master {
private String name;
public Master(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//主人给动物喂食
public void feed(Animal animal , Food food){
System.out.println("主人" + name + "给" + animal.getName() + "吃" + food.getName());
}
// //给狗喂骨头
// public void feed(Dog dog , Bone bone){
// System.out.println("主人" + name + "给" + dog.getName() + "吃" + bone.getName());
// }
//
// //给猫猫喂鱼
// public void feed(Cat cat , Fish fish){
// System.out.println("主人" + name + "给" + cat.getName() + "吃" + fish.getName());
// }
//如果动物很多,食物很多,feed方法很多,不利于维护 → 统一成给动物喂食物
}
测试类
package com.dingjiaxiong.poly_;
/**
* ClassName: Test
* date: 2022/9/3 11:23
*
* @author DingJiaxiong
*/
public class Test {
public static void main(String[] args) {
Master master = new Master("Tom");
Animal animal = new Pig("Peiqi");
Food food = new Rice("东北大米");
// Pig pig = new Pig("Peiqi");
// Rice rice = new Rice("东北大米");
master.feed(animal,food);
}
}
运行结果

方法或对象具有多种形态。是面向对象的第三大特征。
多态是建立在封装和继承基础之上的。
【方法的多态】
举个栗子
package com.dingjiaxiong.poly_;
/**
* ClassName: PloyMethod
* date: 2022/9/3 11:28
*
* @author DingJiaxiong
*/
public class PloyMethod {
public static void main(String[] args) {
//方法重载体现多态
A a = new A();
//传入不同的参数,就会调用不同的sum方法,体现了多态
System.out.println(a.sum(10 ,20));
System.out.println(a.sum(10 , 20 ,30));
//方法重写也体现多态
B b = new B();
a.say();
b.say();
}
}
class B{//父类
public void say(){
System.out.println("B say() 方法被调用...");
}
}
class A extends B{//子类
public int sum(int n1 , int n2){
return n1 + n2;
}
//重载
public int sum(int n1, int n2 ,int n3){
return n1 + n2 + n3;
}
//重写
public void say(){
System.out.println("A say() 方法被调用...");
}
}
运行结果

【对象的多态】
韩老师的几句话
- 一个对象的编译类型和运行类型可以不一致
- 编译类型在定义对象时,就确定了,不能改变
- 运行类型是可以变化的
- 编译类型看定义时 = 号的左边,运行类型看 = 的右边
举个栗子
动物类
package com.dingjiaxiong.poly_.objectpoly_;
/**
* ClassName: Animal
* date: 2022/9/3 11:35
*
* @author DingJiaxiong
*/
public class Animal {
public void cry(){
System.out.println("Animal cry() 动物在叫...");
}
}
狗类
package com.dingjiaxiong.poly_.objectpoly_;
/**
* ClassName: Dog
* date: 2022/9/3 11:37
*
* @author DingJiaxiong
*/
public class Dog extends Animal{
public void cry(){
System.out.println("Dog cry() 小狗汪汪叫...");
}
}
猫类
package com.dingjiaxiong.poly_.objectpoly_;
/**
* ClassName: Cat
* date: 2022/9/3 11:36
*
* @author DingJiaxiong
*/
public class Cat extends Animal{
public void cry(){
System.out.println("Cat cry() 小猫喵喵叫...");
}
}
测试类
package com.dingjiaxiong.poly_.objectpoly_;
/**
* ClassName: PolyObject
* date: 2022/9/3 11:37
*
* @author DingJiaxiong
*/
public class PolyObject {
public static void main(String[] args) {
Animal animal = new Dog();
animal.cry();
animal = new Cat();
animal.cry();
}
}
运行效果

已解决

Java重要特性:动态绑定机制

举个栗子
package com.dingjiaxiong.poly_.dynamic_;
/**
* ClassName: DynamicBinding
* date: 2022/9/3 11:48
*
* @author DingJiaxiong
*/
public class DynamicBinding {
public static void main(String[] args) {
A a = new B(); //向上转型
System.out.println(a.sum());
System.out.println(a.sum1());
}
}
class A{//父类
public int i = 10;
//动态绑定机制
public int sum(){
return getI() + 10;
}
public int sum1(){
return i + 10;
}
public int getI(){
return i;
}
}
class B extends A{
public int i = 20;
public int sum(){
return i + 20;
}
public int getI(){
return i;
}
public int sum1(){
return i + 10;
}
}
运行结果

【多态数组】
现有一个继承结构如下:要求创建 1 个 Person 对象、2 个 Student 对象和 2 个 Teacher 对象, 统一放在数组
中,并调用每个对象say 方法
Person类
package com.dingjiaxiong.poly_.polyarr_;
/**
* ClassName: Person
* date: 2022/9/3 11:54
*
* @author DingJiaxiong
*/
public class Person {//父类
private String name;
private int age;
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 String say(){
return name + "\t" + age;
}
}
Student类
package com.dingjiaxiong.poly_.polyarr_;
/**
* ClassName: Student
* date: 2022/9/3 11:56
*
* @author DingJiaxiong
*/
public class Student extends Person{
private double score;
public Student(String name, int age, double score) {
super(name, age);
this.score = score;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
//重写父类的say
@Override
public String say(){
return "学生" + super.say() + " score = " + score;
}
//特有的方法
public void study(){
System.out.println("学生" + getName() + "正在学Java...");
}
}
Teacher类
package com.dingjiaxiong.poly_.polyarr_;
/**
* ClassName: Teacher
* date: 2022/9/3 11:58
*
* @author DingJiaxiong
*/
public class Teacher extends Person{
private double salary;
public Teacher(String name, int age, double salary) {
super(name, age);
this.salary = salary;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
//重写父类的say方法
@Override
public String say(){
return "老师" + super.say() + "salary = " + salary;
}
//特有方法
public void teach(){
System.out.println("老师" + getName() + "正在教Java...");
}
}
测试类
package com.dingjiaxiong.poly_.polyarr_;
/**
* ClassName: PloyArray
* date: 2022/9/3 11:59
*
* @author DingJiaxiong
*/
public class PloyArray {
public static void main(String[] args) {
Person[] persons = new Person[5];
persons[0] = new Person("Jack",20);
persons[1] = new Student("Marry",18,100);
persons[2] = new Student("Smith",19,30.1);
persons[3] = new Teacher("Scott",30,20000);
persons[4] = new Teacher("King",50,25000);
//遍历多态数组,调用方法
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i].say()); //动态绑定机制
//类型判断 + 向下转型
if (persons[i] instanceof Student){ //判断persons[i]的运行类型是不是Student
Student student = (Student) persons[i];
student.study();
}
else if(persons[i] instanceof Teacher){
Teacher teacher = (Teacher) persons[i];
teacher.teach();
}
else if(persons[i] instanceof Person){
// System.out.println("类型有误");
}
else{
System.out.println("类型有误");
}
}
}
}
运行结果

【多态参数】
方法定义的形参类型为父类类型,实参类型允许为子类类型。
前面的主人喂动物。