JavaSE类与对象 二

JavaSE类与对象 二

本文不会大篇幅的讲类与对象的基础,主要针对面试 以及我在学习类与对象过程中的疑难和困惑

一、多态

关于面向对象三大特征:封装、继承、多态。

  1. 封装隐藏了类的内部实现机制,可以不影响使用的情况下改变类的内部结构,同时保护了数据,对外隐藏内部细节,只暴漏其访问的方法。注:反射会破坏程序的封装性
  2. 继承为了重用父类代码
  3. 多态:程序中定义的引用变量所指向的实例变量的类型,在编译期间并不确定,亦或该引用变量发出的方法调用是哪个类中实现的方法,必须在程序运行时才能确定具体的类。这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上。

总之多态:同一个引用类型,使用不同的实例而执行不同操作

实现多态的三要求:

  1. 要有继承或接口实现
  2. 子类必须重写父类或接口的方法
  3. 父类引用指向子类对象

1.1关于静态绑定和动态绑定

关于绑定:指一个方法的调用和该方法所属的类(所在的类)相关联,意思就是在执行方法调用的时候,jvm所知道调用了哪个类的方法,类和调用方法相关联

静态绑定:程序在执行前就知道了该方法所属的类,即在编译期已经绑定,在java中只有private、static、修饰的方法和构造方法是静态绑定

  1. private:所修饰的方法无法被继承,即子类无法调用该方法
  2. static:被其修饰的方法可以被继承,但子类不能重写父类的静态方法,但如果子类有同名的静态方法,子类可以隐藏父类的该方法。但子类对象向上转型为父类对象时,不论子类有没有定义这个静态方法,都会使用到父类的静态方法
  3. final:被final修饰的方法虽然可以被继承,但无法重写覆盖,即子类可以调用该方法,实际上还是调用父类的方法

总之:一个方法不可以被继承或 继承后不可以被覆盖,那么和个方法就采用静态绑定

动态绑定:运行时绑定是指在程序运行时根据对象类型进行绑定

运行时绑定通过方法表的结构来处理

1.2多态和设计模式

  • 使用设计模式宗旨提高内聚降低耦合,而通过多态可以降低代码耦合度

耦合:模块与模块之间接口的复杂程度,模块之间联系越复杂,耦合度越高,即牵一发动全身

通过多态,使每个模块尽可能独立完成某个特定的子功能

23种设计模式很多都使用到了多态,所以不得谈谈多态的好处

多态提升了代码的可扩展性,在几乎不修改原有代码基础上,加入新的功能,使代码更加健壮,易于维护。

设计模式对于多态的例子比比皆是,面向对象设计有一个最根本的原则“开闭原则”:对添加开放,对修改关闭。而多态提升了代码的可扩展性则体现了开闭原则

1.2.1 对象转型(Casting)
  1. 向上转型:多态中,父类引用指向子类对象就是向上转型的案例,向上转型不需要强制类型转换
  2. 向下转型:即父类对象转为子类对象,此时必须进行强制类型转换

提到类型转换,不得不提到LSP(哈哈,名字起的怪怪的)即里氏替换原则,什么意思呢

LSP:任何基类可以出现的地方,子类一定可以出现。即子类可以使用父类继承下来的所有方法,但反过来却不行(LSP反过来却不成立)。

向上转型是安全的,但向下转型并且对象的具体类型不明确时通常需要instanceof 判断类型

1.2.2 instanceof关键字
对象 instanceof 类(接口)

可以判断引用对象所指向的实例 是否属于一个类,或是继承了这个类(或是实现了这个接口)

实际案例中,通常在重写equals方法中使用instanceof关键字,个人感觉不如之间通过判断其Class对象是否一致来的更细致

二、接口

接口是方法声明的集合,让没有如何关系的对象可以相互联系。接口是实现多继承的手段。

1.1接口与类的区别

  1. 接口中只能定义成员方法,不能定义成员变量。
  2. 接口中的成员方法都是抽象方法(没有具体实现、全为public abstract)
  3. 接口中的成员变量都是public static final 修饰的
  4. 接口没有构造方法,因此不能被实例化
public interface UsbInterface {
	int a =10;  //本质public static fina int a =10;
	void service(); //本质public abstrac void service()
}

1.2 JDK1.8 接口的特性

  1. 静态方法(使用static来修饰放啊,可以通过接口名直接调用)接口中可以添加抽象方法(static),实现类不能重写,只能通过接口名调用

interface Phone {
    static void makePhone(){
        System.out.println("制造手机");
    }
}
class XiaomiPhone implements Phone {
   
    //不能重写,也就无法通过多态来调用这个实现方法,只能从属于子类
    public void makePhone {
        System.out.println("制造小米手机");
    }
}

2.接口中可以添加非抽象方法(default),实现类可以重写(但是必须去掉default),只能通过对象名来调用。此外实现类可以直接使用default方法(不重写default方法)。

public interface Phone {
    default void play(){
        System.out.println("接口调用");
    }
}
public class PhoneImpl implements Phone{
    //实现类可以重写这个default方法,但default关键字不见了
    @Override
    public void play() {
        Phone.super.play(); //调用上级Phone接口的defalut方法
    }

    public static void main(String[] args) {
        Phone phone=new PhoneImpl();
        phone.play();
    }

}

1.3 接口和设计模式(依赖倒置原则)

前面讲了设计模式的 LSP原则和开闭原则,主要针对面向对象的设计目标。那么依赖倒置原则则是面向对象的主要机制

依赖倒置原则:要依赖抽象,而非具体。换句话说,依赖倒置针对的就是接口编程,不针对实现编程。依赖接口编程就是应当使用接口或抽象类,强调的是一个系统内实体间关系的灵活性。如果设计者要遵守“开闭原则”,那么依赖倒置原则则是实现开闭原则的途径。

三、浅谈设计模式几个原则

1、单一职责原则:一个类,最好只做一件事。(解耦)

2、开闭原则:软件实体应当对修改关闭,对扩展开放 (提高扩展性)

3、依赖倒置原则:依赖于抽象,而不要依赖于具体,因为抽象相对稳定。

4、接口隔离原则:尽量应用专门的接口,而不是单一得总接口,接口应该面向用户,将依赖建立在最小得接口上。(解耦)

5、LSP原则:子类必须能够替换其基类

6、聚合复用原则:新对象聚合已有对象,使之成为新对象的成员,从而这些对象达到复用的目的。聚合复用相较于继承耦合更加松散,所以多聚合少继承

7、迪米特法则(最少知识原则):软件实体应该尽可能少的和其他软件实体发生相互作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值