面向对象第四天(Java)

面向对象第四天(Java)

抽象类的特征及应用

接口的特征及应用

面向对象的三大特征之多态性(polymorphism)的特征及应用

向上转型与向下转型

1、抽象类的定义:在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类的特点:
   (1)它可以有默认的方法实现。
   (2)子类使用extends来继承抽象类,如果子类不是抽象类的话,则子类需要将抽象父类的所有抽象方法全部实现。
   (3)抽象类可以有构造方法。
   (4)不能直接实例化,但可通过实现子类来间接实例化。
   (5)抽象类中可以有0~n个抽象方法,且抽象方法的访问修饰符不能为private,因为抽象方法必须交给子类去实现,如果为private则子类根本无法访问到。
   (6)抽象类可以有main方法。
   (7)抽象类可以继承一个类和实现多个接口。
   (8)它比接口的速度快。
   (9)抽象类也可用于多态。
2、final和abstract(抽象类),private和abstract,static和abstract,这些是不能放在一起的修饰符。

为长方形和圆的长度和面积提供统一的计算方式:

package com.hwadee;

public class Calculate {

    public static void main(String[] args) {
        Rect rect=new Rect(3,5);
        double area1 = rect.getArea();
        System.out.println("长方形面积="+area1);
        double len1=rect.getLen();
        System.out.println("长方形周长="+len1);

        Circle circle=new Circle(3);
        double area2 = circle.getArea();
        System.out.println("圆的面积="+area2);
        double len2 = circle.getLen();
        System.out.println("圆的周长="+len2);
    }

}
/**
 * 利用关键字abstract定义一个抽象类
 * 1 抽象类不能被实例化(面试经常问)
 * 2 抽象类是可以被继承的
 * 3 抽象类不能直接实例化,但可通过非抽象的子类来间接实例化;说白了,如果子类是抽象的依然不能实例化
 * 4 在方法名字前加一个关键字abstract叫做抽象方法。
 * 5 抽象方法的特性是:没有方法体!
 */
abstract class MyShape{
    abstract double getArea();
    abstract double getLen();
}
class Rect extends MyShape{
    double length=0.0;
    double width=0.0;
    Rect(){

    }
    Rect(double length,double width){
        this.length=length;
        this.width=width;
    }
    @Override
    double getArea() {
        return length*width;
    }

    @Override
    double getLen() {
        return (length+width)*2;
    }

//  public double getLength() {
//      return length;
//  }
//
//  public void setLength(double length) {
//      this.length = length;
//  }
//
//  public double getWidth() {
//      return width;
//  }
//
//  public void setWidth(double width) {
//      this.width = width;
//  }

}

class Circle extends MyShape{
    public static final double pi=3.14;
    double r=0.0;
    Circle(){
    }
    Circle(double r){
        this.r=r;
    }
    @Override
    double getArea() {
        // TODO Auto-generated method stub
        return 2*pi*r;
    }

    @Override
    double getLen() {
        // TODO Auto-generated method stub
        return pi*r*r;
    }

}

运行结果

3、Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。接口就是抽象方法和常量值定义的集合。
接口的特点:
   (1)接口完全是抽象的,接口不存在方法的实现。
   (2)子类使用关键字implements来实现接口,如果该实现类不是抽象类,那么该类必须实现接口中的所有抽象方法。
   (3)接口不能有构造方法。
   (4)接口不是类,是完全不同的类型。
   (5)接口中抽象方法的访问修饰符只能是public。
   (6)接口中的成员变量只能是public static final修饰。
   (7)接口没有main方法。
   (8)接口可以继承一个或多个接口。
   (9)接口的速度稍慢,因为需要寻找实现类中的实现方法。
   (10)接口也可用于多态。

PencilWithEraser继承了Pen的write方法具备了写功能,现在希望具备擦功能,但Java只支持单继承,只能通过接口实现:

package com.hwadee;

public class SuperInterfaceList {

    public static void main(String[] args) {
        Pen p=new Pen("晨光");
        p.write();

        PencilWithEraser ps=new PencilWithEraser("中华");
        ps.write();
        ps.clean();
        ps.shine();
        System.out.println(PencilWithEraser.color);
    }

}
class Pen{//普通笔类
    String name;
    Pen(){

    }
    Pen(String name){
        this.name=name;
    }
    public void write() {
        System.out.println("会写字!"+name);
    }
}
interface Eraser{
    public static final String color="纯黑色";
    abstract void clean();
}
interface Light{
    abstract void shine();
}
class PencilWithEraser extends Pen implements Eraser,Light{
    PencilWithEraser(){

    }
    PencilWithEraser(String name){
        super(name);
    }
    @Override
    public void write() {
        System.out.println("用铅笔写字!!!"+name);
    }

    @Override
    public void clean() {
        System.out.println(super.name + ":有橡皮擦的铅笔");
    }
    @Override
    public void shine() {
        System.out.println("会发光的铅笔!!!!");
    }

}

运行结果

4、类与类的关系:继承关系,使用关键字extends,只能是单根继承,可以多层继承,只有一个直接父类,可以有多个间接父类。
  类与接口的关系:实现关系,使用关键字implements,类可以实现一个或多个接口,一个类可以在继承一个类的同时实现多个接口。
  接口与接口的关系:继承关系,使用关键字extends,可以继承一个或多个接口。
5、多态性概述:事物存在的多重形态,即同一种事物由于条件不同,产生的结果也不同。在代码中,则是同一个引用类型,使用不同的实例而执行不同的操作。
  实现多态的技术:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
  多态的作用:消除类型之间的耦合关系。
6、多态存在的三个必要条件:要有继承关系、要有方法重写、要有父类引用指向子类对象(格式:Father fa = new Son())
  多态的好处 :
     (1)可替换性(substitutability):多态对已存在代码具有可替换性。
     (2)可扩充性(extensibility):多态对代码具有可扩充性,新增子类不影响已存在类的多态性、继承性等,能够获得更多多态功能。
     (3)接口性(interface-ability):多态是超类通过方法签名,向子类提供一个共同接口,由子类来完善或者覆盖而实现的。
     (4)灵活性(flexibility):它在应用中体现了灵活多样的操作,提高了效率。
     (5)简化性(simplicity):多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

多态中访问成员变量的特点:编译时看父类,运行时看父类。
多态中访问成员方法的特点:编译时看父类,运行时看子类。
多态其实仅限于类的非静态成员方法,只有在运行时才能决定具体调用谁。
通过酒的例子运用继承来对多态进行展示:

package com.hwadee;

public class Polymorphism2 {

    public static void main(String[] args) {
        TwoDragonM t=new TwoDragonM();
        t.trueWords();

        System.out.println("--------");
        //灵活
        Wine w1=new TwoDragonM();
        w1.trueWords();

        int num = w1.number;
        System.out.println("num="+num);

        Wine w2=new FenWine();
        w2.trueWords();
        int num2=w2.number;
        System.out.println("num2="+num2);


    }


//  public static void printMessage(TwoDragonM t) {
//      System.out.println("---> "+t.trueWords());
//  }

//  public static void printMessage(FenWine t) {
//      System.out.println("---> "+t.trueWords());
//  }

    public static void printMessage(Wine t) {
        System.out.println("---> "+t.trueWords());
    }

}

class Wine{
    String brand;
    int grade;
    double price;

    int number=111;

    public String trueWords() {
        System.out.println("酒后吐真言");
        return "酒后吐真言";
    }
}

class TwoDragonM extends Wine{
    int number=222;
    @Override
    public String trueWords() {
        System.out.println("二龙山,真难喝");
        return "二龙山,真难喝";
    }
}

class FenWine extends Wine{
    int number=666;
    @Override
    public String trueWords() {
        System.out.println("汾酒,真棒!!!不愧是酒中之王");
        return "汾酒,真棒!!!不愧是酒中之王";
    }
}

运行结果
通过酒的例子运用接口来对多态进行展示:

package com.hwadee;

public class Polymorphism1 {

    public static void main(String[] args) {
        TrueWords t1=new JiangXiaoBaiWine();
        t1.say("好酒江小白");
        TrueWords t2=new MaoTaiWine();
        t2.say("老字号茅台酒");
    }

}
interface TrueWords{
    public String say(String words);
}
class JiangXiaoBaiWine implements TrueWords{

    @Override
    public String say(String words) {
        System.out.println("江小白不错,"+words);
        return "zzz";
    }

}
class MaoTaiWine implements TrueWords{

    @Override
    public String say(String words) {
        System.out.println("贵州老茅台,"+words);
        return "xixi";
    }

}

运行结果

7、向上转型与向下转型的特点:
     (1)父类引用可以直接指向子类对象,子类引用不能直接指向父类对象。
     (2)把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型。如Father father = new Son();
     (3)把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转型。如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即Son son =(Son)father;其中father前面的(Son)必须添加,进行强制转换。
     (4)upcasting 会丢失子类特有的方法,但是子类overriding 父类的方法,子类方法有效
     (5)向上转型的作用,减少重复代码,父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。体现了JAVA的抽象编程思想。

多态的好处:
   提高了代码的维护性(继承保证)
   提高了代码的扩展性(多态保证)
   可以用父类类型做形式参数或者方法返回值类型,用来接收任意子类对象
多态的弊端:不能直接使用子类的特有属性和方法。可以使用instanceof运算符来进行一个判断,采用向下转型的方式,来调用子类所独有的属性和方法。

实现多态的两种方式:使用父类作为方法形参实现多态、使用父类作为方法返回值实现多态。

对向上转型和向下转型的代码展示:

package com.hwadee;

public class Master {

    //程序的入口 main
    public static void main(String[] args) {
//      Pet pet=new Dog();
//      pet.eat();

        //instanceof

        String s="山西大学的同学表现很好";

        boolean b=s instanceof String;

        System.out.println(b);

        Dog dog=new Dog();
        boolean isDog=dog instanceof Dog;
        System.out.println("isDog="+isDog);

        boolean isPet=dog instanceof Pet;
        System.out.println("isPet="+isPet);

        Master m=new Master();

        m.printInformation(dog);
        m.printInformation(new Cat());

    }

    //普通方法
    public void printInformation(Pet p) {
        if(p instanceof Dog) {
            System.out.println("这个宠物是狗,给它洗澡!");
        }

        if(p instanceof Cat) {
            System.out.println("猫不洗澡,给它一条鱼");
        }
    }
}






//宠物类(父类)
class Pet {
    public void eat() {
        System.out.println("宠物在进食!");
    }
}


//狗类(子类)
class Dog extends Pet {
    public String name = "旺财";

    @Override
    public void eat() {
        System.out.println("狗在吃狗粮!");
    }

    public void catchMouse() {
        System.out.println("狗在抓老鼠!");
    }
}

class Cat extends Pet{
    public String name = "大脸猫";

    @Override
    public void eat() {
        System.out.println("猫在吃小鱼!");
    }

    public void catchMouse() {
        System.out.println("猫在抓耗子!");
    }
}

运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值