面向对象编程02

目录:
一、多态
二、抽象类
三、接口

接面对对象编程01

一、多态

  • 多态:思想->一个事物,表现出不同的形态
  • 封装;增加了程序的安全性
  • 继承:为了代码的重用

什么是多态呢?
理解多态:
* 同一个引用调用同样的方法,表现出多种不同种形态。
* 这种思想就叫多态,用到了动态绑定

class Shape{
    public void draw(){

    }
}
class Rect extends Shape{
    public void draw(){
        System.out.println("■");
    }
}
class Cycle extends Shape{
    public void draw(){
        System.out.println("●");
    }
}
class Flower extends Shape{
    public void draw(){
        System.out.println("❀");
    }
}

public class TestDemo {
    public static void drawMap(Shape shape){
        shape.draw();
    }
    public static void main(String[] args) {
     /*   Rect rect = new Rect();
        drawMap(rect);
        Cycle cycle = new Cycle();
        drawMap(cycle);
        Flower flower = new Flower();
        drawMap(flower);*/

//        或者直接这样
        drawMap(new Rect());
        drawMap(new Cycle());
        drawMap(new Flower());
    }
}

运行结果:
在这里插入图片描述
在这个代码中, 前面的代码是 类的实现者 编写的, TestDemo这个类的代码是 类的调用者 编写的

.当类的调用者在编写 drawMap 这个方法的时候, 参数类型为 Shape (父类), 此时在该方法内部并不知道, 也不关注当 前的shape 引用指向的是哪个类型(哪个子类)的实例. 此时 shape 这个引用调用 draw 方法可能会有多种不同的表现(和 shape对应的实例相关), 这种行为就称为 多态

 * 多态的好处:
 * 1、减低了类的使用成本
 * 2、减低了圈复杂度、避免使用大量的if else
 * 3、可扩展能力强

再来看一下的代码

class Shape{
    public void draw(){

    }
}
class Rect extends Shape{
    public void draw(){
        System.out.println("■");
    }
}
class Cycle extends Shape{
    public void draw(){
        System.out.println("●");
    }
}
class Flower extends Shape{
    public void draw(){
        System.out.println("❀");
    }
}

public class TestDemo {
        public static void drawShapes(){
        Rect rect = new Rect();
        Cycle cycle = new Cycle();
        Flower flower = new Flower();
        String[] shapes = {"cycle","rect","cycle","rect","flower"};
        for(String shape : shapes){
            if(shape.equals("cycle")){
                cycle.draw();
            }else if(shape.equals("rect")){
                rect.draw();
            }else if(shape.equals("flower")){
                flower.draw();
            }

        }
    }

    public static void main(String[] args) {
        drawShapes();
    }

运行结果:
在这里插入图片描述

这是未使用多态的。
再来看使用了多态的代码

public class TestDemo {
    public static void draw(Shape shape){
        shape.draw();
    }
    public static void drawShapes(){
        Shape[] shapes = {new Cycle(),
                new Rect(),new Cycle(),
                new Rect(),new Flower() };
        //数组不是相同数据类型的集合吗,为什么可以这样放呢?
//        按道理说,这里只能放Shape类型的数据,那么这里为什么可以放其他
//        类型的数据类型呢?  //因为发生了向上转型
//    请看这里,Shape shape = cycle;我们知道可以这样做,此处指的就是shape这个引用,
//    引用了cycle所引用的对象,而父类引用子类,发生了向上转型。
       for(Shape shape:shapes){
           draw(shape);
       }
//       顺便复习数组的一种遍历方式
     /*   for(int x : array){
            System.out.print(x+" ");
        }
        System.out.println();
        *//**
         * 原理:便利array里面的每一个元素,把每一个元素取出来
         * 然后都赋值给了x,最后打印x。直到数组array里面的元素全部都遍历完成
         **/
    }

    public static void main(String[] args) {
            drawShapes();

    }

除去注释,可以发现代码简洁了很多,也不用使用大量的if else语句。

二、抽象类

抽象类 抽象方法的类,叫做抽象类

  • 要点:
  • 1、不能被实例化
  • 2、继承了就要重写抽象方法
  • 3、不能是final的

顺便了解下 final 关键字

  • 1.final修饰变量(常量,这个常量不能再被修改)
  • 2.final修饰类,密封类:当前类不能再继承
  • 3.final修饰方法,密封方法:该方法不能进行重写

既然抽象类不能实例化,那么如果我想调用抽象类里面的普通方法,
该怎么做呢?
方法的调用是通过对象的引用来调用,很显然抽象类类无法实例化。

  • 1、可以在子类里通过super来进行调用。super.方法
  • 2、如果这个方法是静态的方法 public static void fun(){},
  • 则可以直接通过类类名来进行调用。Shape.func();
  • 3、Shape shape = new Rect();
  • shape.func();
  • 通过向上转型,抽象类父类引用非抽象类子类,就能够调用抽象类父类的方法
    请看代码:
package 抽象类;

import java.util.Random;

abstract class Shape{
/*    在普通类里是不能有抽象方法的,而在抽象类里头
    既可以拥有抽象方法,也可以有非抽象方法*/

//    抽象方法:如果一个方法,没有具体的实现,那么就可以用abstract修饰
    public abstract void draw();//没有具体的实现
    public void func(){
        System.out.println("faq!!!");
    }
    public static void func2(){
        System.out.println("zfp!!!");
    }
}
class Rect extends Shape{
    @Override
    public void draw() {
        //1、在子类的方法里通过super进行调用
        super.func();

    }
}

public class Testdemo {
    public static void main(String[] args) {
        //1、在子类的方法里通过super进行调用
        Rect rect = new Rect();
        rect.draw();

//        2、静态方法直接通过类名进行调用
        Shape.func2();

//        3、通过向上转型,抽象类父类引用非抽象类子类,就能够调用抽象类父类的方法
        Shape shape = new Rect();
        shape.func();
        //再次复习一下
      /*  如果发生了向上转型,那么通过父类引用,来调用方法 
        或者成员变量的时候,只能调用父类自己的成员变量或者方法!!*/
    }
}

运行结果:
在这里插入图片描述
关于抽象类,还需要注意的几点是:

  • 当一个非抽象类,继承了抽象类,则当前类一定要重写抽象方法
  • 再次用普通类来继承,则之前的抽象类里的抽象方法,都必须重写
abstract class Shape{
    public abstract void draw();//没有具体的实现
    public void func(){
        System.out.println("faq!!!");
    }
}
//当一个非抽象类、继承了抽象类则当前类一定要重写
/*class Rect extends Shape{
    @Override
    public void draw() {

    }
}*/
//如果不想重写的话呢?让普通类变为抽象类
abstract class Rect extends Shape{
    public abstract void funcc();
}
//但是,如果再次用普通类来继承,则之前的抽象类里的抽象方法,都必须重写
//alt+回车,重写
class A extends Rect{

    @Override
    public void draw() {

    }

    @Override
    public void funcc() {
        
    }
}

抽象类的使用:

abstract class Shape{
    public abstract void draw();//没有具体的实现
    public void func(){
        System.out.println("faq!!!");
    }
}
class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("■");
    }
}
class Cycle extends Shape{

    @Override
    public void draw() {
        System.out.println("○");
    }
}
public class Testdemo {
    public static void drawMap(Shape shape){
        shape.draw();
    }
    public static void main(String[] args) {
       drawMap(new Rect());
       drawMap(new Cycle());
//        也是可以发生向上转型,动态绑定的,使用多态
    }
}

运行结果:
在这里插入图片描述

总结:

  • 抽象方法:如果一个方法,没有具体的实现,那么就可以用abstract修饰
  • 1、抽象类不能被实例化。Shape shape = new Shape();//error
  • 2、//在普通类里面是不能有抽象方法的,而在抽象类里
  • 既可以有抽象方法,也可以包含非抽象方法
  • 3、当一个普通的类,继承了一个抽象类,那么这个普通类一定要实现抽象类当中的方法
  • 4、当一个普通类,继承了抽象类,但是又不想实现这个抽象类当中的抽象方法(重写),
  • 那么这个普通类,可以改为,抽象类
  • 5、当一个普通类,继承了上述第4条说的那个抽象类,那么重写的就是两个抽象类的抽象方法了。总结一句话:出来混,迟早要还的!!!
  • 6、抽象类本身是不可以被实例化的,就是为了继承的。自然是不能被final修饰的
  • 7、抽象方法就是为了重写的,你不可以把抽象方法用final修饰。
  • 8、抽象类父类的普通方法,在类外也可以被调用,但需要让父类引用 去 引用子类对象
  • 或者子类中用super访问抽象类父类的成员变量或者成员方法
  • 9、抽象类最大的意义就是为了被继承

三、接口

  • java是单继承
  • 接口的出现就是为了多继承

接口是使用关键字intetface来修饰的,接口也是没办法实例化对象的。与抽象类不同,在接口中,只能有抽象方法。且接口中的所有方法,都是没办法具体实现的。

  • 接口:
  • 1、他是使用关键字intetface来修饰的,接口当中的方法,
  • 默认都是抽象方法。public abstract
  • 2、接口当中,可以定义成员变量。成员变量默认是public static final
  • 3、接口当中的所有方法,都是没有具体实现的、
  • 4、在JDk1.8开始,接口中的方法可以有具体实现,但是这个方法必须是default修饰的。
  • 5、接口也是不可以被实例化的 IShape iShape = new IShape();error
  • *6、接口的使用:类 implements
  • *7、一个类可以实现多个接口,通过关键字implements。但是注意、
  • 一定要重写接口里面的抽象类方法
package 接口;
//    接口在命名的时候一般以大写字母I开头
interface IShape{
    void draw();
//    默认是public abstract void draw();建议这样简写
    int a = 10;
//    默认是public static final a = 10;

  /*  public void func1(){
//        报错了,为什么?
    }*/
    /**
     * 接口中的所有方法,都是没法具体实现的。
     * 但是,在jdk1.8开始,接口中的所有方法可以有具体实现,但是这个
     * 方法必须是default修饰的
     *  比如:
     */
    default void func(){
        System.out.println("faq!!!");
    }

}
class Cycle implements IShape{

    @Override
    public void draw() {
        System.out.println("○");
    }
}
class Rect implements IShape{

    @Override
    public void draw() {
        System.out.println("■");
    }
}
public class Test {
    public static void drawMap(IShape iShape){
        iShape.draw();
    }
    public static void main(String[] args) {
    /*    //接口无法实例化对象
        IShape iShape = new IShape();error*/

/*//        但是可以发生向上转型
        IShape iShape = new Rect();*/
     
        //使用多态
        drawMap(new Rect());
        drawMap(new Cycle());
        }
    }

  • 8、如果两个接口,方法名相同。此时在类里面,
  • 只需要重写这一个方法就好,但是最终调用的,就是这一个方法
  • 建议大家,既然接口都不一样,那么就不要有同样的方法
  • 9、interface D extends A,B 一个接口可以扩展多个接口,
  • 也就是说,D接口具备了A接口和B接口的功能
  • 如果将来D接口被实现,那么这个实现D接口的类,就要重写A,B,D,3个接口的方法了
//接口D扩展了A,B的接口
interface D extends A,B{
    void funcD();
}

本篇完,后续作补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值