面向对象设计
面向对象是相对于面向过程来讲的,指的是把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。从面向过程到面向对象,是程序员思想上从执行者到指挥者的转变。
三大思想:
OOA(object oriented analysis): 面向对象分析
OOD(object oriented design): 面向对象设计
OOP(object oriented programming):面向对象程序
三大特征:
- 封装性(encapsulate):所有内容对外部不可见(attribute尽可能多的是private)
- 继承性(inheritance):将其他功能继承发展
- 多态性(polymorphism):方法的重载(override)本身就是多态的体现
两个名词:
-
类(class): 综合特征
class 由属性和方法构成:
以人为例:
属性(attribute):像人的特征
方法(method):像人的行为 -
对象(object): 根据class造出的个体
两者关系就像图纸(class)和实物(object)的关系
创建对象内存分析:
创建对象时我们会用到堆,栈,方法区
- 栈: 一个线程有一个栈, 栈中有一个指针来控制栈中变量的大小。指针向下移动, 会创建新的内存, 向上移动, 会释放这些内存。存的东西: 对象名字和基本数据类型
例子:Book b1 = 对象地址指向堆存new Book()b1 存在堆中- 堆: 存放对象和数组
new关键字, 是指告诉JVM , 需要明确的去创建一个新的对象 , 去开辟一块新的堆内存空间- 方法区:
方法区存储了每个类的信息,静态变量,常量,编译器编译后代码
Q.为什么不把对象都存在堆里
A.栈中指针移动的方式, 必须要明确移动的大小与范围 , 影响了程序的灵活性。把更大部分的数据 存储到了堆内存中,提升效率。
类(class)
构造方法(构造器 constructor)
要写default constructor 和全parameter constructor
方法的重载(overload)
方法名称相同, 参数类型或参数长度不同, 可以完成方法的重载 ! 方法的重载与返回值无关!
通过传递不同的参数调用方法来完成具体的功能
如何完成:
1.方法名称相同
2.参数列表长度,参数类型,参数类型顺序不同(int,double)(double,int)
构造方法的重载
一个类, 可以存在多个构造方法 :
参数列表的长度或类型不同即可完成构造方法的重载 ~
构造方法的重载 ,可以让我们在不同的创建对象的需求下, 调用不同的方法来完成对象的初始化
1. 封装
为了避免出现逻辑错误, 我们建议对所有属性进行封装,并为其提供setter及getter方法进行设置和取得操作。
this是当前对象
表示当前对象
调用类中的属性
调用类中的方法或构造方法
Static:
一般来说, 只有创建对象才可以使用属性和调用方法。static可以没有创建对象,也能使用属性和调用方法!
存在于方法区归Class自身所有的
2. 继承
继承类型:
单继承,多重层继承,没有多继承(一子多父)
class parent{
}
class child extends parent{
}
Super
父类构造方法
调用super构造方法的代码,放在子类构造方法的第一行
super,访问父类的属性
super,访问父类的方法
Override(重写)
规则:
- signature 应该和父类保持一致
- 访问权限 子的不能比父的权限低
- 父类成员方法之只能被子类重写
- Static和private 方法不能被override
Java (重载 overload) 和 (重写Override) 区别
- 发生的位置
重载:一个类中
重写:子父类中 - 参数列表限制:
重载:必须不同
重写:必须相同 - 返回值类型
重载:返回值类型无关
重写:返回值类型相同 - 参数列表限制:
重载:访问权限无关
重写:子的方法权限必须小于父的方法权限 - 异常处理:
重载:与异常无关
重写:异常范围可以更小,但不能抛出新异常
final
变量变成常量
final修饰的局部变量只能修饰一次(先声明后赋值)
final修饰的成员属性,必须声明时赋值
全局常量
public final static
命名:单词之间 _ 隔开,单词所有字母大写 SQL_INSERT
final 修饰的类不能继承
final 修饰的方法不能被子类重写
抽象类 abstract
抽象类除了不能实例化对象之外(不能用new),其他与普通类一样,所以抽象类必须被继承,被继承的子类(如果不是抽象类)则必须(重写)抽象类中的全部抽象方法
- 需要 @override 重写注解
- 抽象类必须使用abstract class声明
- 一个抽象类中可以没有抽象方法。
- 抽象方法必须写在抽象类或者接口中
格式:
public abstract class 类名{
// 抽象类
public abstract void hello();
}
abstract 不能有final attribute,
但是 abstract 可以有constructor(eg. Default constructor)能有构造方法,而且子类对象实例化的时候的流程与普通类的继承是一样的,都是要先调用父类中的构造方法(默认是无参的),之后再调用子类自己的构造方法。
抽象类和普通类的区别
1、抽象类必须用public或protected修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法)。
2、抽象类不可以使用new关键字创建对象, 但是在子类创建对象时, 抽象父类也会被JVM实例化。
3、如果一个子类继承抽象类,那么必须实现其所有的抽象方法。如果有未实现的抽象方法,那么子类也必须定义为 abstract类
默认缺省为 public
Interface (接口)
如果一个类中的全部方法都是抽象方法,全部属性都是全局常量
全局常量和抽象方法的简写
全局常量编写时, 可以省略public static final 关键字, 别忘了赋值
抽象方法编写时, 可以省略 public abstract 关键字
interface 接口名称{
全局常量 ;
抽象方法 ;
}
class 子类 implements 父接口1,父接口2...{
}
接口和抽象类的区别
1、接口要被类实现 抽象类要被子类继承
2、接口只能声明抽象方法, 抽象类中可以声明抽象方法,也可以写非抽象方法
3、接口里定义的变量只能是公共的静态的常量, 抽象类中的变量是普通变量。
4、接口使用实现来使用, 可以多实现 抽象类使用继承来使用, 无法多继承
5、接口中不允许static(静态方法不能被子类重写,因此接口中不能声明静态方法)
抽象类中可以包含static方法
6、接口不能有构造方法, 但是抽象类可以有
面向接口编程思想
优点:
1、 降低程序的耦合性
2、 易于程序的扩展
3、 有利于程序的维护
3.多态
多态:就是对象的多种表现形式,(多种体现形态)object多态性,从概念上非常好理解,在类中有子类和父类之分,子类就是父类的一种形态 ,对象多态性就从此而来。
多态的使用:对象的类型转换
向上转型:将子类实例变为父类实例
格式:父类 父类对象 = 子类实例 ;
向下转型:将父类实例变为子类实例
格式:子类 子类对象 = (子类)父类实例 ;
instanceof
作用:
判断某个对象是否是指定类的形态,则可以使用instanceof关键字
Object
Object类是所有类的父类(基类),如果一个类没有明确的继承某一个具体的类,则将默认继承Object类。