微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java基础第八讲

目录

一、具体内容

1.1多态的概念

1.2多态的需求

1.3多态的实现步骤

1.4多态的定义

二、抽象类 abstract

思考:

2.1抽象的概念

2.2抽象方法

三、接口

3.1接口的概念

3.2接口的定义及使用

3.3接口的内容


一、具体内容

面向过程编程:注重功能的实现

面向对象编程:注重调用

面向对象的三大特征: 封装,继承,多态

java面向对象的特征: 封装,继承,多态, 抽象,接口

1.1多态的概念

一种物体有多种形态

1.2多态的需求

对于一个动物园,有一个饲养员Feed()方法,需要喂养狗,狗有eat()方法,然后还要喂养猫,猫也有eat()方法,后面也许还会喂养别的动物,每添加一种动物,都需要单独添加

Animal

public class Animal {    
    // 吃的方法    
    public void eat(){        
        System.out.println("吃东西");    
    }
}

Cat

public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫在吃东西");
    }
}

Dog

public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗在吃东西");
    }
}

Feeder

public class Feeder {
    public void Feed(Dog dog){
        System.out.println("饲养员在喂狗");
        dog.eat();// 狗在吃东西
    }
   
    public void Feed(Cat cat){
        System.out.println("饲养员在喂猫");
        cat.eat();
    }
}

Test

public class Test {
    public static void main(String[] args) {
        // 饲养员喂养dog
        Feeder Feeder = new Feeder();
        Dog dog = new Dog();
        Feeder.Feed(dog);
        //饲养员喂养cat
        Cat cat= new Cat();
        cat.eat();
    }
}

假如动物园一直添加动物,那每个动物都需要这样添加,非常麻烦

但是使用多态能够解决这个问题:

 public class Feeder {
 //如果参数是一只猫,那参数就是猫,
    //如果参数是一只狗,那参数就是狗,参数是什么,此时animal就是什么
    //并且调用该子类的方法,
    public void Feed(Animal animal){
        animal.eat();
    }
}
对应的Test

 Animal yingwu =new YingWu();//允许将子类类型赋值给父类类型
        //如果子类对象赋值给父类对象,父类对象在运行的时候就会使用子类对象的特征运行
        //父类指向子类的方法
        yingwu.eat();

1.3多态的实现步骤

1)创建父类Animal 方法eat()

2)创建Animal的子类Cat Dog Pig 并且都重写eat()

3)创建饲养员类 喂动物 方法 Feed(Animal animal)

4)创建饲养员的对象 创建animal的对象 饲养员对象里的Feed(具体的动物)

1.4多态的定义

多态polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型赋值给父类类型,父类引用子类对象。 此时父类指向子类的内存地址。

多态的前提是继承和方法重写

向上转型: ⽗类引⽤⼦类对象(⾃动成⽴,缺点是失去调⽤⼦类独有⽅法的能⼒)

向下转型:⼦类引⽤⽗类对象(强制转换),此时可以调用子类对象中的方法属性缺点是容易造成类型转换错误

//向上转型*** ⽗类引⽤⼦类对象(⾃动成⽴,缺点是失去调⽤⼦类独有⽅法的能⼒)
        Animal dog1=new Dog();//向上转型***  此时dog是Animal类型,是父类的对象
        //向下转型***   ⼦类引⽤⽗类对象(强制转换),此时可以调用子类对象中的方法属性。缺点是容易造成类型转换错误
        Dog dog2=(Dog)dog1;//向下转型***  将Animal的dog对象强制转换为Dog类的对象
        dog2.watchDoor();//Dog类的对象就可以调用dog所有的方法

向下转型时,会出现类型转换异常

/*
        Cat cat =(Cat) dog1;//为同级子类
        
        ClassCastException:类型转换异常
        Exception in thread "main" java.lang.classCastException: com.aaa.exer.Dog cannot be cast to com.aaa.exer.Cat
    at com.aaa.exer.Test.main(Test.java:34)
    将指向Dog类的dog1强制转换为同级Cat类的对象cat时,就会出现这种错误
*/
       /*
        Animal animal =new Animal();
        Dog dog3=(Dog)animal;
        此时是指向Animal类的对象animal强制转换为Dog类的dog3,也会报错
        ClassCastException:类型转换异常
        Exception in thread "main" java.lang.classCastException: com.aaa.exer.Dog cannot be cast to com.aaa.exer.Cat
    at com.aaa.exer.Test.main(Test.java:34)
        */

二、抽象类 abstract

思考:

1)饲养员能喂 Animal 吗?

不能:因为Animal只是我们抽象出的一个父类,为了更好的解决代码问题。Animal并不是实际存在的对象。但是人可以喂养具体的某一个动物。

2)Animal能吃吗?

能:可以吃,但是只是具有吃的行为。

动物都有吃的行为,但是一定要具体到某一个动物我们才可以说这个动物吃什么。

3)Animal中不写eat()可以吗?

不可以。因为子类的eat()是继承并重写父类的eat()方法,如果不写编译都不能通过。因为多态的前提是继承和方法重写。

4)dog,cat,pig中不写eat()可以吗?

可以。语法不会报错,但运行时会执行的是父类的eat()方法,此时就没有意义了。

2.1抽象的概念

抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。

就是说抽象的父类只有相应行为的概念,具体的行为要在每一个具体的子类中才有。

2.2抽象方法

public abstract class Animal {
    //abstract 抽象的关键字
    //抽象类中的方法必须都是公开的,不能是私有的
    public  void eat(){
        System.out.println("这是一个动物,动物都要吃东西");
    }
    //[权限修饰符]  abstract  返回值  方法名();//没有方法体{}
    public abstract void aaa();
    //abstract修饰的类就是抽象类 修饰的方法就是抽象方法
    //含有抽象方法的类一定是抽象类
    //抽象类不一定有抽象方法
    //抽象类里面可以有普通的方法
    //抽象类就是让子类来继承的,
    //子类继承了抽象类之后,必须重写父类里面的抽象方法,若该子类不想重写父类方法,否则需要把该子类变成抽象类
    //抽象类有构造方法,但是不能被new出来
}

三、接口

3.1接口的概念

接口: 在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。 一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

一,Java接口,Java语言中存在的结构,有特定的语法和结构;

二,一个类所具有的方法的特征集合:java接口

逻辑上的抽象:接口

可以先把接口当做一个特殊的抽象类来看待

3.2接口的定义及使用

接口定义的格式

[权限修饰符] interface 接口名{}

接口的使用步骤

1.接口中的方法不能直接使用,必须有一个实现类来实现接口

[权限修饰符] class 类名 implements 接口1,接口2,接口3{}
//可以同时实现多个接口
public class Mouse implements USB{}

2.接口的实现类必须(覆盖重写)实现 接口中所有的抽象方法

注:如果实现类没有重写接口中的方法,那么就需要把该实现类变为抽象类

3.创建实现类的对象,进行方法调用

接口命名时必须以大写I开头,用来表示这是一个接口
public interface IUsb {
   public static final double PI=3.14;
   void write();
}
//实现类
public class Upan implements  IUsb{
    @Override
    public void write() {
    }    
    //接口是需要实现  implements:实现
    //格式: public class 类名 implements 接口
    //类实现接口就要实现接口中所有的方法
    
}

3.3接口的内容

接口中可以包含的内容 :成员常量、抽象(静态)方法方法

常量是不可变的;

public interface IUsb {
    //接口是用interface来修饰的
    
    //常量
   public static final double PI=3.14;
    //认必须是public static final 来修饰
    //想访问必须用static  要让别的类调用所以要用public来修饰
    
    //抽象方法
    void write();
    //接口中的方法是抽象方法 只有方法名,没有方法体
    //接口中的抽象方法必须是两个固定的关键字修饰  public abstract,这两个关键字可以省略不写
    
    //方法(jdk1.8以后的新增内容)
    //不是必须被实现类的实现的方法,通过对象调用接口中的方法。
    //为什么要有方法? default 增强接口的通用能力。
    //default   返回值 方法名(){} //方法方法体
    
    //静态方法
     public static void aaa(){
        System.out.println("这是静态方法");
    }
    //接口里是没有构造方法的 不能被new出来
}
//常量的使用  直接使用   接口名.常量名
public class Test {
    public static void main(String[] args) {
        double pi = IUsb.PI;
    }
}

案例

public interface Usb {
    //接口的常量 认使用public static final修饰
    //public static final可以不写 认的就是
    public static final int AEG=5;
​
    //接口中的抽象方法 认使用public abstract修饰
    public abstract void work();
    void read();
​
    //方法 
    //default修饰  实现类可以重写也可以不重写
    default  void write(){
        System.out.println("这是方法调用了");
    }
    
    //静态方法
    //静态方法在实现类里不能被重写,但是可以通过接口名.方法调用
    public static void aaa(){
        System.out.println("这是静态方法");
    }
}
public interface Usb3 {
    void look();
    void see();
}
public class Mouse implements Usb {
​
    @Override
    public void work() {
        System.out.println("鼠标开始工作了");
    }
    @Override
    public void read() {
        System.out.println("鼠标开始读取了");
    }
}
​
public class Upan implements Usb{
​
    @Override
    public void work() {
        System.out.println("U盘被插入了");
    }
    @Override
    public void read() {
        System.out.println("U盘被读取");
    }
}
public class FengShan implements Usb,Usb3{
    @Override
    public void work() {
​
    }
    
    @Override
    public void read() {
    
    }
//实现类重写Usb接口中的方法
    @Override
    public void write() {
        System.out.println("风扇开始转");
    }
​
    @Override
    public void look() {
        System.out.println("USB3被调用了");
    }
​
    @Override
    public void see() {
​
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        //接口+多态
        //接口指向实现类的对象
        Usb mouse = new Mouse();
        Usb.aaa();//只能通过接口名.静态方法调用
        mouse.read();//调用子类Mouse的重写方法
        mouse.write();//调用父类Usb的方法
        System.out.println(Usb.AEG);//接口中的常量可以直接调用
  //多态 Usb可以变成 mouse 或者 upan
        Usb upan = new Upan();
        upan.work();//调用子类Upan的重写方法
        upan.read();//调用子类Upan的重写方法
​
        Usb fengshan = new FengShan();
        fengshan.write();//重写了接口的方法
​
        Usb3 fengshan1=new FengShan();
        fengshan1.look();//调用另外一个接口的look()方法
    }
}

注意事项:

类与类之间是单继承的

类与接口是多实现的一个类可以实现多个接口(这个要将所有实现的接口中的抽象方法都实现),方便后期维护(修改,扩展)

接口与接口之间是多继承的一个接口A如果继承(extends)了接口B和接口C,那么A接口可以同时拥有B和C接口的所有功能,并且还可以拥有属于自己的方法

接口没有构造方法

接口多态一个USB接口可以表现出鼠标形态,键盘的形态,U盘的形态

接口和抽象类的区别? (提问)

抽象类 接口
构造方法 有构造方法,但是不能被new出来 没有构造方法,不能被new出来
继承 单继承,只能继承一个抽象父类 但是可以多级继承 一个接口可以继承多个接口, 一个类可以实现多个接口
抽象方法 抽象方法要用public abstract修饰,不能省略,只有方法名,没有方法 抽象方法认用public abstract修饰,可以省略,只有方法名,没有方法
抽象方法 抽象类里面可以没有抽象方法,有抽象方法的类必须是抽象类 接口中如果不是抽象方法方法用default修饰
常量 常量名要大写 接口中的常量是用public static final修饰的,public static final可以不写

原文地址:https://www.jb51.cc/wenti/3281762.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐