1.基本概念:对象、类、属性和方法
1.1 对象(Object)
对象有两个特征:状态和行为
- 状态:对象所包含的数据
- 行为:对象支持的操作,是指面向对象的函数
1.2 类(Classes)
每个对象都有一个类。类定义了方法(Methods)和字段(Fields)
4.继承和覆盖
4.1 继承
继承(Inheritance): 从父类继承得到父类的字段和方法,主要目的是为了代码复用
可重写方法(Rewriteable Method): 允许重新实现的方法。在Java中,默认情况下方法是可重写的,即没有特殊的关键字
严格继承(Strict inheritance): 子类只能向超类添加新方法,不能覆盖它们。如果在Java程序中无法覆盖某个方法,则必须在其前面加上关键字final
4.2 覆盖/重写
方法重写(Overriding): 允许子类或子类提供已由其某个父类或者祖宗类提供的方法的特定实现。一般重新写一遍,但是改点东西,增添子类独特的内容
要求:
- 重写的方法要有相同的名称、相同的参数或签名以及相同的返回类型
- 执行的方法的版本将由用于调用它的对象确定,父类就调父类的方法,子类就调子类重写的方法
- 不要改变方法原意
4.3 抽象类
抽象方法(Abstract method): 只有定义没有实现
抽象类(Abstract class): 抽象类不能实例化(不能用new 生成对象),继承某个抽象类的子类在实例化时,所有父类中的抽象方法必须已经实现
接口(Interface): 只有抽象方法的抽象类
5.多态、子类型、重载
5.1 三种多态类型
- 特殊多态(Ad hoc polymorphism): 当一个函数表示不同,取决于单个指定类型和组合的有限范围。一个方法可以有多个同名的实现(方法重载)
- 参数化多态(Parametric polymorphism): 编写代码时没有提及任何特定类型,即泛型编程
- 包含多态(Subtyping): 一个变量名字可以代表多个类的实例(子类型),即一般我们所讲的多态
5.2 特殊多态与方法重载
当拥有同一个名字的函数在几个不同的类型上工作,对于每个类型可能以不同的方式运行时,就获得了特殊多态性。
多个方法具有同样的名字,但有不同的参数列表或返回值类型,这被称为重载,这方便了客户端的使用。对重载函数的调用将根据调用的上下文运行该函数的特定实现,允许一个函数调用根据上下文执行不同的任务。
函数的重载Overload是静态的多态,即在编译阶段,决定了函数到底如何执行,而方法的重写Override是在运行阶段进行动态检查的,而这有很大区别
重载有以下几点规则:
- 不同的参数列表
- 相同/不同的返回值类型
- 相同/不同的public/private/protected
- 异常
- 可以在同一个类内重载,也可在子类中重载
5.3 参数化多态与泛型编程
参数多态性是指方法针对多种类型时具有同样的行为,在运行时根据具体指定类型确定,在Java中这被称为泛型(Generics)编程
泛型编程是一种编程风格,其中数据类型和函数是根据待指定的类型编写的,随后在需要时根据参数提供的特定类型进行实例化
使用泛型变量的三种形式:泛型类、泛型接口和泛型方法
- 类中如果声明了一个或多个泛型变量,则为泛型类;这些类型变量称为类的类型参数
- 如果接口声明了一个或多个类型变量,则该接口是泛型的;它定义一个或多个作为参数的泛型变量,在之后的方法中可能会使用到
- 如果方法声明了一个或多个类型变量,则该方法是泛型的;这些泛型变量称为方法的形式类型参数,形式类型参数列表的形式与类或接口的类型参数列表相同
形如:public < T > T genericMethod
5.4 包含多态
继承/子类型的好处:代码重用、建模灵活性
在Java中:每个类只能直接扩展一个父类;一个类可以实现多个接口
如果在Java中声明子类型(例如,实现接口),那么必须确保子类型的规范至少与父类型的规范一样强
子类型多态:不同类型的对象可以统一的处理而无需区分,每个对象的行为都与其类型有关
LSP原则:如果S是T的子类型,则T类型的对象可以替换为S类型的对象(即T类型的对象可以替换为任何子类型的对象),而不改变T的任何期望属性。
6.Java中一些重要的对象方法
我们要重写一些重要的对象方法,在Java中有三个:
- equals() – 判断相等
- hashCode() – 返回哈希值
- toString() – 输出字符串的格式
一般有IDE直接生成就行了,无需烦心
7.设计优质的类
不可变类的好处:
- 简单
- 固有线程安全
- 可以自由分享
- 不需要防御性拷贝
- 优秀的组件
如何编写不可变类
- 不提供任何变值器
- 确保不能重写任何方法
- 使所有字段成为final字段
- 将所有字段设为private
- 确保任何可变组件的安全性
- 实现toString()、hashCode()、clone()、equals()等
我们基本上都需要构造不可变类,除非万不得已
当构造可变类时也要注意,要最小化可变性,构造函数应该完全初始化实例
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!