Java学习之路(十一)| 面向对象(三)

一、多态

1、多态的概念:

多态是同一行为具有多个不同表现形式或形态的能力,多态就是同一个接口,使用不同的实力而执行不同的操作。
多态、封装、继承是面向对象的三大特性。 如:在生活中跑的动作,小猫、小狗、和大象跑起来不一样。

2、多态的具体实现形式:

父类类型 变量名 = new 子类对象;

举例:

//Test.java文件夹
package Animal_Cat_Dog;

public class Test {
    public static void main(String[] args) {
        Animal A=new Animal();
        A.Eat();//调用父类的Eat方法
        System.out.println("-----创建一个Animal类的对象-----");
        Animal B=new Cat();
        B.Eat();//Cat类创建了自己的Eat方法,所以这里会调用自己的Eat方法
        System.out.println("-----创建一个Cat类的对象-----");
        Animal C=new Dog();
        C.Eat();//Dog类没有创建自己的Eat方法,所以调用的是父类Animal的Eat方法
        System.out.println("-----创建一个Dog类的对象-----");
    }
}

//Animal.java文件夹
package Animal_Cat_Dog;
public class Animal {
    public void Eat(){
        System.out.println("动物吃东西。");
    }
}

//Cat.java文件夹
package Animal_Cat_Dog;
public class Cat extends Animal {
    public void Eat(){
        System.out.println("猫吃鱼");
    }

}

//Dog.java文件夹
package Animal_Cat_Dog;
public class Dog extends Animal {

}

在这里插入图片描述当使用多态方法调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的重写方法。
使用多态的好处:是程序有良好的扩展,并可以对所有类的对象进行通用处理。实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。
在这里插入图片描述

3、引用类型转换

父类对象和子类对象之间的转换分为了向上转型和向下转型。

(1)向上转型

通过子类(小范围)实例化父类对象(大范围),这种属于自动转换。
意义:当我们需要多个同父的对象调用某个相同的方法时,通过向上转换后,可以确定参数的统一,方便程序设计。

缺点:对象的向上转型是安全的,但是会失去子类新增的属性(变量)或者方法。就是说子类对象被看作为父类的类型,只能访问父类的属性和方法,以及子类的重写。
在这里插入图片描述
在Cat子类中创建了一个age属性,在调用过程中使用会报错。这就是向上转型失去了子类新增的属性或者方法的具体体现。
在这里插入图片描述

(2)向下转型

通过父类(大范围)示例化子类对象(小范围),这种属于强制转换。

为什么需要向下转型:
当使用多态方式调用时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说不能调用父类没有而子类拥有的方法为了在多态方式中调用子类特有的方法,需要乡下转型。

instanceof关键字

通过父类强制转换为子类,从而调用子类特有的方法。通过instanceof可以判断某对象是否是某类的实例(该类或该类的父类),如果是则返回true,否则返回false。

if(A instanceof Cat)//如果A是Cat类型,就返回true
{
	Cat CatA=(Cat)A;//将A类强转为Cat类
	//CatA 可以执行猫类特有的方法
}

//在实际编程中的用法
if(A instanceof Cat){
	Cat CatA=(Cat)A;//将A类强转为Cat类
	//CatA 可以执行猫类特有的方法
}else if(A instanceof Dog){
	Dog DogA=(Dog)A;//将A类强转为Dog类
	//DogA 可以执行狗类特有的方法
}

在这里插入图片描述

总结

1、看一个对象能够访问哪些属性,看等于号=左边定义的是什么类型
父类类型:只能访问父类的属性。
子类类型:可以访问父类的属性,子类新增,子类重写属性。
2、看一个对象最终能访问那个方法,看=右边是什么类型的对象
父类类型:只能访问父类的方法。
子类类型:父类的方法,及子类新增、重写的方法。

二、Object类

1、Object类概述

所有的类,都是以继承结构存在的。如果没有显示的父类,默认继承Object类。class Person{}
相当于class Person extends Object{}

  1. Object类是超类、基类,所有类的直接或间接父类,位于继承树的最顶层。
  2. 任何类,如果没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接继承。
  3. Object类所定义的方法,是所有对象都具备的方法。
  4. Object类型可以存储任何对象。
  5. 作为参数,可以接受任何对象。
  6. 作为返回值,可以返回任何对象。

2、常用方法

a、getClass();

返回引用中存储的实际对象类型。
通常用于判断两个引用中实际存储对象类型是否一致。

A.getClass()//调用示例

b、hashCode();

返回该对象的十进制的哈希值(十进制地址值)。
可以判断两个对象是不是相同的地址。

A.hashCode();//调用示例

c、toString();

返回该对象的字符串表示。
可以根据程序需求覆盖该方法,如展示对象的各个属性值。IDEA工具提供自动生成。

A.toString();//调用示例

d、equals()

比较两个对象地址是否相同。
可以进行覆盖比较两个对象内容是否相同。

A.equals(B);调用示例

equals 重写步骤

  1. 比较两个引用是否指向同一个对象。
  2. 判断object是否为null
  3. 判断两个引用指向的实际对象类型是否一致
  4. 强制类型转换
  5. 依次比较各个属性是否相同

重写equals()示例

    @Override
    public boolean equals(Object obj) {
        if (this==obj){
            return true;
        }
        if(obj==null||this.getClass()!=obj.getClass()){
            return false;
        }
        Animal animal=(Animal)obj;//将Object向下转型为Animal
        if(this.name.equals(animal.name)){
            return true;
        }else {
            return false;
        }
    }

e、finalize()方法:前期简要了解,在学JVM会详细讲解

  • 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列。
  • 垃圾对象:没有有效引用指向此对象时,为垃圾对象。
  • 垃圾回收:由GC销毁垃圾对象,释放数据存储空间。
  • 自动回收机制:JVM内存耗尽,一次性回收所有垃圾对象。
  • 手动回收机制:使用System.gc();通知JVM执行垃圾回收。

三、抽象类

将子类的共同特征进行抽取,抽象成一个父类。如果有的功能在父类中定义了,但是没有具体的实现,那么可以定义为抽象的。等待子类实现即可。

作用:

  • 可以被子类继承,提供共性属性和方法。
  • 可声明为引用,更自然的使用多态。

抽象类:包含抽象方法的类

  • 被abstract修饰的类,称为抽象类;
  • 抽象类意为不够完整的类、不够具体的类;
public abstract class 类名{
}

抽象方法:没有方法体的方法。抽象的方法一定要定义在抽象类里面。

public abstract 返回值类型 方法名(参数);

代码示例:

@Override
class Cat extends Animal{//抽象类的子类一定要实现抽象方法
	System.out.println("猫吃鱼。");
}

abstract class Dog extends Animal{//不实现抽象方法只能将子类也定义为抽象类
	
}

public abstract class Animal{抽象方法一定要定义在抽象类中
	public abstract void eat();//抽象方法
}

注意事项:

  • 抽象类不可以直接创建对象,原因:调用抽象方法没有意义。
  • 只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象。否则该子类还是一个抽象类,需要再被子类继承直到实现所有抽象方法。
  • abstract关键字不能和static,private,final等关键字搭配使用。

四、接口

引用数据类型:数组接口

接口是Java语言中一种引用类型,是方法的集合。接口的定义与类的定义方式相似,关键字不同。接口使用interface关键字,但它也会被编译成.class文件。

  • 接口中偶尔也定义静态常量。public static final double PI=3.14;

接口是一种约定、契约,一种规范。

Ⅰ、 接口定义

1、含有抽象方法

抽象方法:使用abstract关键字修饰,可以省略,没有方法体。该方法供子类实现使用。
代码如下:

public interface InterFaceName{
	public abstract void method();
}

2、含默认方法和静态方法

默认方法:使用default修饰,不可省略,供子类调用或者子类重写。
静态方法:使用static修饰,供接口直接调用。
代码如下:

Usb.java文件

//创建一个鼠标接口
class Mouse implements Usb{
    @Override
    public void start() {
        System.out.println("鼠标开始工作。");
    }

    @Override
    public void stop() {
        System.out.println("鼠标停止工作。");
    }

    @Override
    public void fun1() {
        System.out.println("鼠标的默认方法。");
    }
}
class Keyboard implements Usb{

    @Override
    public void start() {
        System.out.println("键盘开始工作。");
    }

    @Override
    public void stop() {
        System.out.println("键盘停止工作。");
    }
}

public interface Usb {
    //接口中含有两个抽象方法
    public abstract void start();
    public abstract void stop();

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

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

Test.java文件

public class Test {
    public static void main(String[] args) {
        //错误写法:Usb USB=new Usb();接口不能示例化

        Usb mouse=new Mouse();
        mouse.start();
        mouse.stop();

        mouse.fun1();//调用默认方法,用示例对象调用

        Usb.fun2();//静态方法用接口名去调用
    }
}

3、含默认方法和私有方法

私有方法:使用private修饰,供接口中的默认方法或者静态方法调用

public interface Usb(){//在默认方法和静态方法中调用
	private void method(){
		//执行语句
	}
}

总结:

  • 子类和父类的关系:extends
  • 实现类和接口的关系:implements
  • 非抽象子类实现接口:必须重写接口中所有抽象方法、继承接口的默认方法,可以重写
  • 接口中的静态方法只能使用接口名调用。

Ⅱ、 接口的应用

1、一个类可以实现多个接口

接口中的功能都没有方法体,由子类来明确。

代码示例:

interface Fun1{
    void fun1();
}
interface Fun2{
    void fun2();
}



public class Zi implements Fun1,Fun2 {//一个类可以实现多个接口
    @Override
    public void fun1() {
        
    }

    @Override
    public void fun2() {

    }
}

2、一个类继承的同时可以实现接口

当一个类已经继承了一个父类,它又需要拓展额外的功能,这时接口就派上用场了
代码示例:

class Fu{//一个父类
    
}

public class Zi extends Fu implements Fun1,Fun2 {//一个类可以实现多个接口
    @Override
    public void fun1() {

    }

    @Override
    public void fun2() {

    }
}

3、接口的多继承

两个类之间通过继承产生关系,接口和类之间通过实现产生关系,两个接口的关系?
多个接口之间可以使用extends进行继承

interface Fun1{//接口一
    void fun1();
}
interface Fun2{//接口二
    void fun2();
}

interface Children extends Fun1,Fun2{//接口的继承
    @Override
    void fun1();

    @Override
    void fun2();

    public void children_play();
}

4、接口和抽象类的区别

相同点:

  • 二者都存在抽象方法。
  • 不能创建对象,不能实例化。
  • 可以作为引用类型。
  • 具备Object类中所定义的方法。

不同点:

  • 接口所有属性都是公开静态常量,个别变量使用public static final修饰
  • 接口所有方法都是公开抽象方法,个别方法使用public abstract修饰
  • 接口没有构造方法、动态代码块、静态代码块

5、接口的好处

  • 接口的出现降低了耦合性
  • 设计与实现完全分离,更容易更换具体实现
  • 更容易搭建程序框架
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值