面对对象多态,对象转换,抽象类

7月10日面向对象3

1.多态

 一种事物的多种形态|多种表现形式
    行为的多态
    一个行为的不同的实现方式

多态的前提:
    类的继承|接口的实现

多态的最终体现:
    父类的引用指向子类的对象

注意: 如果多态想要有意义,需要配合方法的重写,多态才有意义

多态调用:
    会调用子类中重写的方法

多态的实现效果:
    配合方法的重写,当父类引用指向不同的子类对象,同一个方法具有不同的实现方式-->行为多态
public class Class001_Polymorphic {
    public static void main(String[] args) {
        //对应类型的数据赋值给对应类型的变量
        int i = 1;
        Person p = new Person();
        Student s = new Student();

        //多态的最终体现
        Person person = new Teacher();
        person.test();
    }
}

class Person{
    void test(){
        System.out.println("Person");
    }
}

class Student extends Person{
    void test(){
        System.out.println("Student");
    }
}

class Teacher extends Person{
    void test(){
        System.out.println("Teacher");
    }
}

Teacher

多态调用成员的特点:
    父类引用调用
        成员变量:
            编译运行看父类|左边|类型

        成员方法:
            编译看父类|左边|类型
            运行找子类|右边|对象



   注意: 多态是行为的多态
         多态如果不配合方法的重写没有意义
         父类引用对子类新增内容不可见
public class Class002_Test {
    public static void main(String[] args) {
        //父类引用指向子类对象
        Fu fu = new Zi();

        System.out.println(fu.name);

        fu.test();
         Zi zi2=new Zi();
        System.out.println(zi2.name);
        zi2.test();

    }
}

class Fu{
    String name = "Fu";
    public void test(){
        System.out.println("Fu");
    }
}

class Zi extends Fu{
    String name = "Zi";

    public void test(){
        System.out.println("Zi");
    }

    //新增内容
    public void test2(){
        System.out.println("Zi2");
    }
}

Fu
Zi
Zi
Zi

/*
 * 做题四大原则:
 * 一、继承链:自己没有找父
 *        A
 *        |
 *        B
 *      /    \
 *  C     D
 * 二、 编译看类型、确定方法,运行找对象
 * 
 * 三、就近最优原则
 * 
 * 四、父类引用对子类新增方法不可见
 *
 * 编译期间能够确定所调用的方法
 */

public class Class003_PolyTest {
   public static void main(String[] args) {
      A a1=new A();  //  A and D  A and A
      //多态调用
      A a2=new B();  //  A and D  B and A
      B b =new B();  //  B and B  B and A  A and D
      C c=new C();
      D d =new D();  
      System.out.println(a1.show(b)); //A and A
      System.out.println(a1.show(c)); //A and A
      System.out.println(a1.show(d)); //A and D
      String e=a2.show(b);
      System.out.println(e); //B and A
      System.out.println(a2.show(c)); //B and A
      System.out.println(a2.show(d)); //A and D
      System.out.println(b.show(b));  //B and B
      System.out.println(b.show(c));  //B and B
      System.out.println(b.show(d));  //A and D
   }

}

class A{
   public String show(D obj){
      return ("A and D");
   }
   public String show(A obj){
      return ("A and A");
   }
}

class B extends A{
   //新增方法
   public String show(B obj){
      return ("B and B");
   }
   //重写方法
   @Override
   public String show(A obj){
      return ("B and A");
   }
}

class C extends B{
}

class D extends B{
}

2.对象的转换

基本数据类型 : 类型转换
    int i  = 1;
    byte b ;
    自动类型提升
        long l = i;
    强制类型转化
        b = (byte)i;
引用数据类型 : 转型
    类型的大小 : 看继承关系|实现关系
        父类>子类
    向上转型 : 自动类型提升
        Person p = new Student(); --> 多态

        多态调用: 对子类新增内容不可见

    向下转型 : 强制类型转换
        Student s = (Student)p;

        通过s引用调用Student类型所有的内容

ClassCastException 类型转换异常
           引用强转类型的时候,没有转为指向的子类对象类型,转为了其他子类类型,出现的异常

预防出出现类型转换异常->instanceof 运算符

引用 instanceof 类型:
    判断前面的引用是否指向后面类型的对象或者后面类型子类的对象,是->true  不是->false
public class Class001_Cast {
    public static void main(String[] args) {
        //多态
        Person p = new Student();

        //需求: 调用子类中独有的study
        //向下转型  从父类引用转为对应类型的子类引用,就可以调用子类中的所有内容

        if(p instanceof Teacher){
            Teacher s = (Teacher)p;
            s.study();
        }else if(p instanceof Student){//虽然当前的p是个父类引用,但实际上它所指向的是一个子类对象(判断对象是根据new后面的类)
            Student s = (Student)p;
            s.study();
        }

        System.out.println(p instanceof Person);  //true
        System.out.println(p instanceof Object);  //true
        System.out.println(p instanceof Student); //true
        System.out.println(p instanceof Teacher); //false

    }
}

class  Person{}

class Student extends Person{
    void study(){
        System.out.println("学习");
    }
}

class Teacher extends Person{
    void study(){
        System.out.println("老师学习!!!!");
    }
}

3.抽象类

抽象的
    抽象类: 被abstract修饰的类
    抽象方法: 被abstract修饰的方法
         没有方法体
         存在与抽象类中

开发部门:
    Develop 开发部  work()
    java攻城狮  work(){"服务器端开发"}
    web程序猿   work(){"客户端开发"}


抽象类的特点:
    1.抽象类不能实例化
    2.抽象类可以定义任意内容(属性,功能(抽象的方法,具体的方法))
    3.抽象方法必须要求被重写
    4.抽象类使用: 通过具体子类对象使用
        具体子类: 重写所有的抽象方法 + 按需新增
        抽象子类: 按需重写抽象方法 + 按需新增
    5.一个抽象方法一旦被重写,可以不再被重写,根据需求决定
    6.abstract不能与private,final,static,native 一起使用
    7.抽象类可以实现多态
abstract class Develop {
    //方法体: 不知道怎么写,不知道写什么
    public abstract void work();

    //具体方法
    public void sleep(){
        System.out.println("胡吃海喝!!!!");
    }
}

//子类
class Java  extends Develop{

    @Override
    public void work() {
        System.out.println("服务器端开发");
    }

    //新增功能
    public void mr(){
        System.out.println("与测试,产品,谈论...探讨...");
    }
}

//抽象子类
abstract class Web extends Develop{
    //public abstract void work();
    public void haha(){
        System.out.println("每天哈哈傻笑...");
    }
}

4.练习

import java.util.Objects;
import java.util.Scanner;
import java.util.regex.Pattern;

/*
    披萨制作练习:
        1. 编写程序实现比萨制作。需求说明编写程序,接需要制作收用户输入的信息,选择的比萨。可供选择的比萨有:培根比萨和海鲜比萨。
        实现思路及关键代码
        1) 分析培根比萨和海鲜比萨
        2) 定义比萨类
        3) 属性:名称、价格、大小
        4) 方法:展示
        5) 定义培根比萨和海鲜比萨继承自比萨类
        6) 定义比萨工厂类,根据输入信息产生具体的比萨对象

 */
public class Class001_PizzaFactroy {
    public static void main(String[] args) {
        //1.键盘输入
        Scanner sc = new Scanner(System.in);
        //2.接收用户输入信息
        System.out.println("请输入想要制作的披萨 1.培根披萨 2.海鲜披萨");
        int num  = sc.nextInt();
        System.out.println("请输入披萨大小");
        int size  = sc.nextInt();
        System.out.println("请输入披萨价格");
        double price  = sc.nextDouble();

        Pizza pizza = null;
        if(num==2){
            System.out.println("请输入海鲜配料信息");
            String info  = sc.next();

            //3.创建披萨对象
            pizza = new SeaPizza("海鲜披萨",price,size,info);
        }
        pizza.show();
    }
}

//父类
abstract class Pizza{
    //属性:名称、价格、大小
    //方法:展示
    private String name;
    private double price;
    private int size;

    //构造器
    public Pizza() {
    }

    public Pizza(String name, double price, int size) {
        this.name = name;
        this.price = price;
        this.size = 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 int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    @Override
    public String toString() {
        return "Pizza{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", size=" + size +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Pizza pizza = (Pizza) o;
        return Double.compare(pizza.price, price) == 0 &&
                size == pizza.size &&
                Objects.equals(name, pizza.name);
    }

    //show 展示
    public void show(){
        System.out.println(name);
        System.out.println(price);
        System.out.println(size);
    };
}

//海鲜披萨
class SeaPizza extends Pizza{
    //独有属性
    private String info;

    public SeaPizza() {
    }

    public SeaPizza(String name, double price, int size, String info) {
        super(name, price, size);
        //super.setName(name);
        //super.setPrice(price);
        //super.setSize(size);
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "SeaPizza{" +
                "info='" + info + '\'' +
                "} " + super.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        SeaPizza seaPizza = (SeaPizza) o;
        return Objects.equals(info, seaPizza.info);
    }

    @Override
    public void show() {
        super.show();
        System.out.println(info);
    }
}

5.接口

 接口 :
     接口可以理解为是一个特殊的抽象类
     功能的集合
     引用数据类型
     接口可以帮助定义规范
     解耦-->降低耦合度
     类是单继承,接口多实现的


定义 :
     interface 定义接口

组成:
     jdk7及之前:
         公共的静态的常量
             public static final--> 修饰符可以任意省略
         公共的抽象的方法
             public abstract --> 修饰符可以任意省略

     jdk8及之后:

使用:
     1.接口不能实例化
     2.接口需要通过实现类的对象使用
     3.父类需要通过子类继承  extends  -->父类中的成员,子类继承父类有权可以直接使用
       接口需要通过实现类去实现  implements --> 因为接口中几乎都是抽象方法没有方法体,需要实现类自己实现方法体,所有叫做实现
       接口的实现与类的继承很像,都拥有了父类的成员使用权,或者拥有接口中定义的功能,但是一个侧重点在拿过来就用,一个侧重点在拿过来要实现才能用
     4. 接口的使用:
         具体的实现类 : 重写所有的冲向方法 + 按需新增
         抽象的实现类 : 按需重写 + 按需新增
     5.接口可以多实现,类只能单继承
     6.如果一个类同时继承父类实现接口,要求先继承后实现
public class Class001_Interface {
    public static void main(String[] args) {
        System.out.println(MyInterface.PI);

        //根据具体的实现类的对象使用
        MyImpl my = new MyImpl();
        my.test1();
        my.test1();
        my.haha();

    }

}

//接口
interface MyInterface{
    //公共的静态的常量
    double PI = 3.14;

    //公共的抽象的方法
    public abstract void test1();
    void test2();
}
interface A{
    void a();
}
interface B{
    void b();
}

//具体实现类
class MyImpl  extends Object implements MyInterface,A,B {

    @Override
    public void test1() {

    }

    @Override
    public void test2() {

    }
    //新增内容
    public void haha(){}

    @Override
    public void a() {

    }

    @Override
    public void b() {

    }
}

//抽象实现类
abstract class MyImpl2 implements MyInterface{
    @Override
    public void test1() {

    }
}
/*
    注意:
        1.父类与接口无法完全相互代替,如果可以建议使用接口,因为接口可以多实现非常灵活
        2.类与类之间只能继承
          类与接口之间,只能是类实现接口
          类与类之间只能单继承
          类与接口之间可以多实现
          接口与接口之间,可以多继承

        3.接口可以实现多态  接口引用指向实现类对象
 */
public class Class002_Interface {

    public static void main(String[] args) {
        testSmoke(new Teacher());
    }

    /**
     * 会继续吸烟的人
     * @param s Smoke接口的实现类对象
     */
    public static void testSmoke(Smoke s){  //Smoke s = new Teacher();  接口多态
        s.smoking();
    }
}

//父类
class Person{
    public String name;
    public int age;

    public void sleep(){
        System.out.println("闭上眼睛休息");
    }
}

//接口  吸烟
interface Smoke{
    void smoking();
}
//喝酒
interface Drink{
    void drinking();
}
interface Code{
    void code();
}

//总和接口 : 吸烟 喝酒 打牌...
interface Amusement extends Smoke,Drink{}

//子类
class Teacher extends Person implements Smoke,Code,Drink{
    public String subject; //学科

    public void teach(){
        System.out.println("教书育人");
    }

    @Override
    public void smoking() {
        System.out.println("标准的吸烟方法");
    }

    @Override
    public void code() {

    }

    @Override
    public void drinking() {

    }
}

class Student extends Person implements Code{

    @Override
    public void code() {

    }
}

//社会人
class SocialMan extends Person implements Amusement{
    @Override
    public void smoking() {
        System.out.println("社会人吸社会烟...");
    }

    @Override
    public void drinking() {

    }

标准的吸烟方法

/*
    jdk8中新增:
        1.静态方法 : 可以定义方法体
          使用: 通过接口名使用

        2.默认方法 : 可以定义方法体
           显示的被default修饰
           使用: 通过实现类对象使用
 */
public class Class003_Inteface {
    public static void main(String[] args) {
        Swim.test();
        //实现类对象
        new SwimImpl().test2();
    }
}

interface Swim{
    void swimming();

    //静态方法
    public static void test(){
        System.out.println("静态方法");
    }

    //默认方法
    public default void test2(){
        System.out.println("默认方法");
    }
}

class SwimImpl implements Swim{
    @Override
    public void swimming() {

    }

静态方法
默认方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值