一、面向对象与面向过程
1.简介
面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了
但是在面向对象设计之前,广泛采用的是面向过程,面向过程只是针对于自己来解决问题。面向过程的操作是以程序的基本功能实现为主,实现之后就完成了,也不考虑修改的可能性,面向对象,更多的是要进行子模块化的设计,每一个模块都需要单独存在,并且可以被重复利用,所以,面向对象的开发更像是一个具备标准的开发模式。
在面向对象定义之中,也规定了一些基本的特征:
(1)封装:保护内部的操作不被破坏;
(2)继承:在原本的基础之上继续进行扩充;
(3)多态:在一个指定的范围之内进行概念的转换。
对于面向对象的开发来讲也分为三个过程:OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)
2.类与对象
类:类是一个模子,描述了该对象应该具有什么特征。
对象:对象是类的实例,由照着类这个模子创建出的实例。
对象具有一定的属性和方法, 特征就是属性,属性既类中的成员变量,方法既类中的成员函数。
类与对象之间的关系?
类:事物的描述。
对象:该类事物的实例。在java中通过new来创建的
class Peopletext{
//类中的属性
String name;
int high;
int weig;
boolean sex;
//类中的方法
void eat(){
System.out.println("正在吃饭");
}
void run(){
System.out.println("正在锻炼");
}
}
public static void main(String[] args) {
//在计算机中通过new来创建一个实例
Peopletext people=new Peopletext("atwoodTom");// people就是一个类类型的引用变量,指向了该类的对象
//要使用对象中的(内容\方法)可以通过 对象.(成员\方法) 的形式来完成调用。
System.out.println(people.name);
people.run();
}
类加载
我们编写的java文件都是保存着业务逻辑代码。java编译器将 .java 文件编译成扩展名为 .class 的文件。.class 文件中保存着java转换后,虚拟机将要执行的指令。当需要某个类的时候,java虚拟机会加载 .class 文件,并创建对应的class对象,将class文件加载到虚拟机的内存,这个过程被称为类的加载。
类加载的过程
分为加载,验证,准备,解析,初始化
加载:类加载过程的一个阶段,ClassLoader通过一个类的完全限定名查找此类字节码文件,并利用字节码文件创建一个class对象
验证:目的在于确保class文件的字节流中包含信息符合当前虚拟机要求,不会危害虚拟机自身的安全,主要包括四种验证:文件格式的验证,元数据的验证,字节码验证,符号引用验证。
准备:为类变量(static修饰的字段变量)分配内存并且设置该类变量的初始值,(如static int i = 5 这里只是将 i 赋值为0,在初始化的阶段再把 i 赋值为5),这里不包含final修饰的static ,因为final在编译的时候就已经分配了。这里不会为实例变量分配初始化,类变量会分配在方法区中,实例变量会随着对象分配到Java堆中
解析:这里主要的任务是把常量池中的符号引用替换成直接引用
初始化:这里是类记载的最后阶段,如果该类具有父类就进行对父类进行初始化,执行其静态初始化器(静态代码块)和静态初始化成员变量。(前面已经对static 初始化了默认值,这里我们对它进行赋值,成员变量也将被初始化)
类加载器
实现通过类的权限名获取该类的二进制字节流代码块叫做类加载器
类加载器的分类
自定义类加载器,应用程序类加载器,扩展类加载器,启动类加载器
双亲委派机制
工作过程:如果一个类收到了 类加载的请求,他首先不会去尝试加载这个类,而是先把请求委派给父类加载器去完成,每层的类加载器都是如此,因此类加载的请求最终都会传输到顶层的启动类加载器中去。如果父类加载器反馈自己无法完成这个加载请求。子类加载器才会尝试自己去加载
双亲委派机制的优点
采用双亲委派模式的好处就是Java类随着它的类加载器一起具备一种带有优先级的层次关系,通过这种层级关系可以避免类的重复加载,当父亲已经加载了该类的时候,就没有必要子类加载器(ClassLoader)再加载一次。其次是考虑到安全因素,Java核心API中定义类型不会被随意替换,假设通过网路传递一个名为java.lang.Integer的类,通过双亲委派的的模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字类,发现该类已经被加载,并不会重新加载网络传递过来的java.lang.Integer.而之际返回已经加载过的Integer.class,这样便可以防止核心API库被随意篡改。可能你会想,如果我们在calsspath路径下自定义一个名为java.lang.SingInteger?该类并不存在java.lang中,经过双亲委托模式,传递到启动类加载器中,由于父类加载器路径下并没有该类,所以不会加载,将反向委托给子类加载器,最终会通过系统类加载器加载该类,但是这样做是不允许的,因为java.lang是核心的API包,需要访问权限,强制加载将会报出如下异常。
java.lang.SecurityException:Prohibited package name: java.lang
3.封装
封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。
封装的作用
隐藏对象的属性和实现细节,仅仅对外提供访问方式,将变化隔离便于使用
封装的优点
-
- 良好的封装能够减少耦合。
-
- 类内部的结构可以自由修改。
-
- 可以对成员变量进行更精确的控制。
-
- 隐藏信息,实现细节。
4.继承
继承是使用已经存在的类的定义作为基础创建新类,新类的定义可以增加一些属性或者新的方法。也可以用父类的功能,但是不可以 选择性的继承父类。通过继承我们能够非常方便的复用以前的代码
继承的特点
1.java中只能存在单个继承不可以实现多继承;即一个类只能有一个父类
2.java继承可以多层继承;
3.子类拥有父类非 private 的属性、方法。
4.子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
5.提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
继承的好处
提高了代码的复用能力,给多态提供了前提
继承的格式
class 父类{
}
class 子类 extends 父类{
}
implements关键字
使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
public interface A {
public void eat();
public void sleep();
}
public interface B {
public void show();
}
public class C implements A,B {
}
super和this
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。可以理解为指向父类的一个指针(离自己最近的一个父类)
this关键字:指向自己的引用。可以理解为指向对象的一个指针
public person(String name){
this