1.多态
Java有三大特性:封装 继承 多态
多态: 多种形态。是面向对象的三大特性之一。多态是建立在封装和继承之上
方法的重写和重载就是方法的多态的体现形式
package com.qfedu.a_fun;
class Person {
public void eat () {
System.out.println("吃饭");
}
public void eat (String food) {
System.out.println("吃" + food);
}
}
class Man extends Person {
@Override
public void eat() {
System.out.println("吃枸杞");
}
@Override
public void eat(String food) {
System.out.println("吃"+ food);
}
}
public class Demo1 {
public static void main(String[] args) {
}
}
1.一个对象 的编译类型和运行类型是不一样
2.编译类型是在定义对象的时候,就已经确定好的
3.运行类型是可以改变的
4.编译类型看=的左边 运行类型看 =的右边
Person person = new Person();
多态: 父类引用指向子类的对象
Animal animal = new Dog();
Animal anima1 = new Cat();
package com.qfedu.b_duotai; class Animal { public void cry () { System.out.println("动物在叫......"); } } class Dog extends Animal { @Override public void cry() { System.out.println("汪汪汪......"); } //自己独有的方法 public void eat () { System.out.println("狗吃shit"); } } class Cat extends Animal { @Override public void cry() { System.out.println("喵喵喵....."); } public void sleep () { System.out.println("睡觉打呼噜"); } } public class Demo1 { public static void main(String[] args) { //多态 父类的引用指向子类的对象 Animal animal = new Dog(); animal.cry(); //父类的引用是指向不了子类独有的方法的,就意味着 //父类的引用不能调用子类独有的方法 //animal.eat(); Animal animal2 = new Cat(); animal2.cry(); //animal2.sleep(); } }
注意事项:
多态:
1.必须有继承
2.必须有重写
3.=左边是 =右边是子类的对象
4.在开发中,一个方法的参数是父类的引用。但是真正传的值是子类的对象
之前有一个作业 : 人喂狗,狗吃饭。 人喂猫,猫吃饭
package com.qfedu.c_duotai;
class Person {
// public void feed (Dog dog) {
// dog.eat();
// }
// public void feed (Cat cat) {
// cat.eat();
// }
//在开发中,一个方法的参数是父类的引用。但是真正传的值是子类的对象
public void feed (Animal animal) {
animal.eat();
}
}
interface Animal {
public void eat ();
}
class Dog implements Animal{
@Override
public void eat () {
System.out.println("狗在吃骨头......");
}
}
class Cat implements Animal{
@Override
public void eat () {
System.out.println("猫吃鱼......");
}
}
public class Demo1 {
public static void main(String[] args) {
Person person = new Person();
/**
* Animal animal = new Cat();
* public void feed (Animal animal) {
animal.eat();
}
*/
person.feed(new Cat());
/**
* Animal animal = new Dog();
* public void feed (Animal animal) {
animal.eat();
}
*/
person.feed(new Dog());
}
}
案例
编写程序实现比萨制作。需求说明编写程序,可供选择的比萨有:培根比萨和海鲜比萨。 实现思路及关键代码 1) 分析培根比萨和海鲜比萨 2) 定义比萨类 3) 属性:名称、价格、大小 4) 方法:展示 5) 定义培根比萨和海鲜比萨继承自比萨类 6) 定义比萨工厂类,根据输入信息产生具体的比萨对象 PizzaFactory { createPizza(Pizza);//如果传的参数培根披萨就是生产培根披萨 如果传的是海鲜披萨就是生产的海鲜披萨 }
package com.qfedu.c_duotai;
class Pizza {
private String name;//名字
private double price;//价格
private double size;//尺寸
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getSize() {
return size;
}
public void setSize(double size) {
this.size = size;
}
//展示方法
public void getInfo () {
}
}
class BaconPizza extends Pizza{
@Override
public void getInfo() {
System.out.println("披萨的名字为:" + getName() + ",披萨的价格:" + getPrice() + ",披萨的尺寸:" + getSize());
}
}
class SeaPizza extends Pizza {
@Override
public void getInfo() {
System.out.println("披萨的名字为:" + getName() + ",披萨的价格:" + getPrice() + ",披萨的尺寸:" + getSize());
}
}
//披萨的生产工厂
class PizzaFactory {
//生产披萨的方法
public void createPizza (Pizza pizza) {
pizza.getInfo();
}
}
public class Demo3 {
public static void main(String[] args) {
Pizza pizza = new SeaPizza();
pizza.setName("海鲜披萨");
pizza.setPrice(78.9);
pizza.setSize(6.7);
PizzaFactory pizzaFactory = new PizzaFactory();
pizzaFactory.createPizza(pizza);
//生产培根披萨
Pizza pizza2 = new BaconPizza();
pizza2.setName("培根披萨");
pizza2.setPrice(45.9);
pizza2.setSize(7.2);
pizzaFactory.createPizza(pizza2);
}
}
本质就是:父类的引用指向子类对象
语法格式:
父类 父类引用 = new 子类();
将子类的对象赋值给了父类的引用。小范围(子类) 转为大范围(父类)自动转
父类的引用可以调用父类的所有成员方法,可以调用子类的重写父类的方法,但是不能调用子类独有的方法。
package com.qfedu.d_duotai;
class Person {
public void eat () {
}
}
class Student extends Person {
@Override
public void eat() {
System.out.println("学生吃饭,吃披萨");
}
public void sleep () {
System.out.println("中午不谁下午崩溃!!!");
}
}
public class Demo1 {
public static void main(String[] args) {
Person person = new Student();//向上转型
person.eat();
//person.sleep();
}
}
##### 1.4.2多态向下转型
> 语法格式:
>
> ```
> 父类类型 父类引用 = new 子类();
> 子类类型 子类引用 = (子类类型)父类的引用;向下转型
> ```
>
> 需要强转
```java
package com.qfedu.d_duotai;
class TestA {
//Object 是所有类的父类
public void test (Object obj ) {
//必须给我打印一个String类型的狗蛋,我不要Object类型的狗蛋
// String str = (String) obj;
// System.out.println(str);
int i1 = (int)obj;
System.out.println(i1);
}
}
public class Demo4 {
public static void main(String[] args) {
TestA testA = new TestA();
//testA.test("狗蛋");
Object object = "狗蛋";
testA.test(98);
testA.test('狗');
}
}
```
1.多态
父类的引用指向子类的对象
父类引用 对象 = new 子类();
真实的开发的时候,一个方法的参数传的是一个类的父类对象形参。但是真正调用这个
方法的时候,传的是子类对象。实参
2.
向上转型=====》 父类引用指向了子类的对象 子类赋值给父类引用
向下转型=====》将父类的引用赋值给子类 父类赋值给子类引用
注意点:
先向上转型,再向下转型
比较操作符,返回值是布尔类型的数据
语法格式:
对象引用 instanceof 运行类型
用来判断对象的运行类型(=右边), 是否是xx类型或者xx类型的子类
目的是为了在强转的时候不出现问题
总结: 左边 的辈分小(对象的引用) 右边辈分大(类) 屡试不爽
package com.qfedu.e_instanceof;
class AA {}
class BB extends AA {}
public class Demo1 {
public static void main(String[] args) {
BB bb = new BB();
BB bb1 = new BB();
AA aa = new AA();
//instanceof 的左边放的对象的引用,右边是类
System.out.println(bb instanceof BB);//true
System.out.println(bb1 instanceof BB);//true
//判断对象bb是否是AA的对象或者子类的对象
System.out.println(bb instanceof AA);//true
System.out.println(aa instanceof AA);//true
System.out.println(aa instanceof BB);//false
//总结: 左边 的辈分小(对象的引用) 右边辈分大(类) 屡试不爽
AA aa2 = new BB();
System.out.println(aa2 instanceof AA);//true
System.out.println(aa2 instanceof BB);//true
//
Object object = new Object();
System.out.println(object instanceof AA);//false
System.out.println(object instanceof Object);//true
String string = "qwer";
System.out.println(string instanceof Object);//true
}
}
package com.qfedu.e_instanceof;
class Employee {}
class Monkey {
//这个方法的返回值是一个字符串
public String xixi(Object obj) {
//Object obj = new String("狗蛋");
//obj instanceof String
if (obj instanceof String) {
String string = (String)obj;
return "传给我的 参数是字符串类型的数据";
} else if (obj instanceof Integer) {
Integer i1 = (Integer)obj;
return "传给我的 参数是int类型的数据";
} else if (obj instanceof Employee) {
Employee employee = (Employee)obj;
return "传给我的参数是一个Employee对象";
}
else {
return "参数不合法";
}
}
}
public class Demo3 {
public static void main(String[] args) {
Monkey monkey = new Monkey();
//System.out.println(monkey.xixi("狗蛋"));
//System.out.println(monkey.xixi(89));
Employee employee = new Employee();
System.out.println(monkey.xixi(employee));
String string = new String();
}
}