简单总结面向对象

简单总结面向对象 面向对象 (Object Oriented,OO)面对对象的思想对软件开发相当重要它的概念和应用甚至已超越了程序设计和软件开发扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD 技术、人工智能等领域。面向对象是一种 对现实世界理解和抽象的方法是计算机编程技术发展到一定阶段后的产物。面向过程 (Procedure Oriented)是一种 以过程为中心 的编程思想。这些都是以什么正在发生为主要目标进行编程不同于面向对象的是谁在受影响。比如说 给你一个任务你要思考怎么做。如果你的思维方式是我先做什么再做什么……这叫面向过程如果思维方式是我先做一个什么东西来做这件事再做一个什么东西来做那件事然后它们怎么相互配合……这叫面向对象。类类可以看作是一个模板或者图纸系统通过类的定义来建造对象。类我们叫做class。 对象我们叫做Object,instance(实例)。以后我们说某个类的对象某个类的实例。是一样的意思。类可以看成是一类对象的模板对象可以看成是一个类的实例。类是用于描述同一类型的对象的一个抽象概念类中定义了这一类对象所具有的公共属性 方法。 一个类里一般有三种常见成员属性field方法method构造器construcotr。类的定义属性field成员变量属性用于定义该类或该类对象包含的数据或者说静态特征。属性的作用范围是整个类体。在定义成员变量时可以对其初始化如果不对其初始化Java讲使用默认的值对其初始化Java的默认值为 0 但不同的类型表达出的结果不同如浮点型为“0.0” 字符型为“ ‘\u0000’ ” , 布尔型为 “false 所有引用类型为 “null”。属性的定义格式一般为[修饰符] 属性类型 属性名 [默认值] ;方法方法用于定义该类或者该实例的行为特征和功能实现。方法是类和对象行为特征的抽象。方法和类似于面向过程中的函数。面向过程中函数是最基本的单位整个程序由一个个函数调用组成。面向对象中整个程序的基本单位是类方法从属于类和对象的。方法的定义格式一般为[修饰符] 方法返回值类型 方法名(形参列表) {// n条语句}构造方法构造器 constructor构造器也叫构造方法用于对象的初始化。构造器是一个创建对象时被自动调用的特殊方法目的是对象的初始化。构造器的名称与类名一致。Java通过“ new”关键字来调用构造器从而返回该类的实例是一种特殊的方法。构造的声明格式一般如下[修饰符] 类名(形参列表){//n条语句 }构造方法也是方法只不过有特殊的作用而已。与普通方法一样构造方法也可以重载。构造器的四个要点1构造器通过new关键字调用2构造器虽然有返回值但是不能定义返回值类型返回值类型肯定是本类不能在构造器里使用 return 返回某个值。3如果我们没有定义构造器则编译器会自动定义一个无参的构造方法。如歌已定义则编译器不会自动添加。4构造器的方法必须和类名一致堆heap几乎所有创建的Java对象实例都是被直接分配到堆上的。堆被所有的线程共享在堆上的区域会被垃圾回收器做进一步划分列如 新生代 老年代的划分。 Java虚拟机在启动的时候可以使用“Xmx”之类的参数指定堆区域的大小。方法区Method Area方法区和堆一样也是所有线程共享存储配虚拟机加载的元Meta数据包括类信息 常量 静态变量 即时编译器编译后的代码等数据。Java方法区时一种Java虚拟机的规范。由于方法区存储的数据和堆中存储的数据一致实质上也是堆因此在不同的JDK版本中方法区实现的方式不一样。JDK7以前方法区就是堆中的“永久代”。JDK7开始去“永久代”把静态变量、字符串常量池都挪到了堆内存中。DK8以后“永久代”不存在了。存储的类信息、编译后的代码数据等已经移动到了MetaSpace元空间中元空间并没有处于堆内存上而是直接内存直接占用的本地内存NativeMemory。运行时常量池Run-Time Constant Pool)(方法区中)这是方法区的一部分。常量池主要存放两大类常量1.字面量Literal如文本字符串、final常量值。符号引用存放了与编译相关的一些常量因为Java不像C那样有连接的过程因此字段方法这些符号引用在运行期就需要进行转换以便得到真正的内存入口地址。直接内存Direct Memory直接内存并不属于Java规范规定的属于Java虚拟机运行时数据区的一部分。Java的NIO可以使用Native方法直接在java堆外分配内存使用DirectByteBuffer对象作为这个堆外内存的引用。虚拟机栈简称栈的特点如下1 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧存储局部变量、操作数、方法出口等2. JVM为每个线程创建一个栈用于存放该线程执行方法的信息实际参数、局部变量等3. 栈属于线程私有不能实现线程间的共享4. 栈的存储特性是“先进后出后进先出”栈是由系统自动分配速度快栈是一个连续的内存空间堆的特点如下1. 堆用于存储创建好的对象和数组(数组也是对象)2JVM只有一个堆被所有线程共享3: 堆是一个不连续的内存空间分配灵活速度慢方法区又叫静态区,也是堆特点如下1: 方法区是JAVA虚拟机规范可以有不同的实现。i. JD7以前是“永久代”ii. JDK7部分去除“永久代”静态变量、字符串常量池都挪到了堆内存中iii. JDK8是“元数据空间”和堆结合起来。2:. JVM只有一个方法区被所有线程共享3: 方法区实际也是堆只是用于存储类、常量相关的信息4: 用来存放程序中永远是不变或唯一的内容。参数传值机制Java中方法中所有参数都是“值传递”也就是“传递的是值的副本”。 也就是说我们得到的是“原参数的复印件而不是原件”。因此复印件改变不会影响原件。基本数据类型参数的传值传递的时值的副本。副本改变不会影响原件。引用类型参数的传值传递的是值的副本。但是引用类型指的是“对象的地址”。因此副本和原参数都指向了同一个“地址”改变“副本指向对象的的值也意味着原参数指向对象的值也发生了改变”。this关键字对象的创建和this的本质 构造方法是创建Java对象的重要途经通过new关键字调用构造器构造器也确实返回该类的对象但这个对象并不完全由构造器负责创建。创建一个对象分以下4步1分配对象空间并将对象成员变量初始化为0或空2执行属性值的显示初始化3执行构造方法4返回对象的地址给相关的变量this的本质就是创建好的对象地址 由于在构造方法调用前对象已经创建。因此在构造放法中也可以使用this代表“当前对象”。this的最常用法1在程序中产生二义性之处应使用this来指明当前对象普通方法中this总是指向调用该方法的对象。构造方法中this总是要指向正要初始化的对象。2使用this关键字调用重载的构造方法皮面相同的初始化代码。但只能在构造方法中用并且必须位于构造方法的第一句。3this不能用于static方法中。static关键字在类中用static声明的成员变量为静态变量也称之为类变量。类变量的生命周期和类相同在整个应用程序的执行期间都有效。它有以下特点1为该类的公用变量属于类被该类的所有实例共享在类被载入是显示初始化。2对于该类的所有对象来说static成员变量只有一份。被该类的所有对象共享3一般用“类名.类属性/方法”来调用。也可以通过对象引用或类名不需要实例化访问静态成员。4在static方法中不可以访问非static的成员。静态初始化块构造方法用于对象的初始化静态初始化块用于类的初始化操作在静态初始化块中不能访问非static成员。静态初始化执行顺序1上溯到Object类先执行Object的静态初始块在向下执行子类的静态初始化块 直到类的静态初始化块为止。2构造方法的执行顺序也是先上溯到Object类先执行Object的构造方法在向下执行子类的构造方法 直到类的构造方法块为止。包机制package import包机制是Java中管理类的重要类的重要手段。开发中我们会遇到大量同名的类通过包我们很容易对解决类重名的问题也可以实现对类的有效管理。 包对于类相当于文件夹对于文件的作用。package我们通过package实现对类的管理package的使用有两个要点1通常类的第一句是非注释性语句。2包名域名倒着写即可再加上模块名便于内部管理类。注意事项1写项目时都要加包不要使用默认包。2com.gao和com.gao.car这两个包没有任何关系时两个完全独立的包。只是逻辑上看起来后者是前者的一部分。导入类import如果我们要使用其他包的类需要使用import导入从而可以再本类中直接通过类名来调用否则就需要书写类的完整包名和类名。import后便于编写代码提高可维护性。注意要点1Java会默认导入Java.lang包下的所有类因此这些类我们可以直接使用。2如果导入两个同名的类只能用包名类名来显示调用关系静态导入 static import是在JDK1.5多的新功能其作用是用于导入指定类的静态属性这样我们就可以直接使用静态属性。继承继承是面向对象的三大特征之一他让我们更加容易实现对于已有类的扩展 更加容易实现对于现实世界的建模。继承的两个主要作用1代码的复用更加容易实现类的扩展2方便事务的建模 instanceof是二元运算符左边是对象右边是类当对象是右边类或子类所创建对象时返回true否则返回false。继承的使用要点1 父类也称作超类、基类。子类派生类等。2 Java中只有单继承没有像C那样的多继承。多继承会引起混乱使得继承链过于复杂系统难于维护。3 Java中类没有多继承接口有多继承。4 子类继承父类可以得到父类的全部属性和方法 (除了父类的构造方法)但不见得可以直接访问(比如父类私有的属性和方法)。5如果定义一个类时没有调用extends则它的父类是java.lang.Object。方法的重写override子类通过重写父类的方法可以用自身的行为替换父类的行为。方法的重写就是实现多态的必要条件。方法的重写需要符合以下的3个要点1. “ ” 方法名、形参列表相同。2. “≤”返回值类型和声明异常类型子类小于等于父类。3. “≥” 访问权限子类大于等于父类。final关键字1修饰变量: 被他修饰的变量不可改变。一旦赋了初值就不能被重新赋值。2修饰方法该方法不可被子类重写。但是可以被重载3修饰类: 修饰的类不能被继承。比如Math、String等。继承和组合我们可以通过继承方便的复用已经定义类的代码。还有一种方式也可以方便的实现“代码复用”那就是“组合”。 “组合”不同于继承更加灵活。“组合”的核心就是“将父类对象作为子类的属性”然后“子类通过调用这个属性来获得父类的属性和方法”。组合比较灵活。继承只能有一个父类但是组合可以有多个属性。所以有人声称“组合优于继承开发中可以不用继承”但是不建议大家走极端。 继承除了代码复用、也能方便我们对事务建模。所以对于“is -a”关系建议使用继承“has-a”关系建议使用组合。Object类的基本特征Object类是所有Java类的根基类也就意味着所有的Java对象都拥有Object类的属性和方法。如果在类的声明中未使用extends关键字指明其父类则默认继承Object类。to String方法Object类中定义有public String toString()方法其返回值是 String 类型。Object类中toString方法的源码为public String toString() {return getClass().getName() “” Integer.toHexString(hashCode());}根据如上源码得知默认会返回“类名16进制的hashcode”。在打印输出或者用字符串连接对象时会自动调用该对象的toString()方法。和equals方法“”代表比较双方是否相同。如果是基本类型则表示值相等如果是引用类型则表示地址相等即是同一个对象。Object类中定义有public boolean equals(Object obj)方法提供定义“对象内容相等”的逻辑。Object 的 equals 方法默认就是比较两个对象的hashcode是同一个对象的引用时返回 true 否则返回 false。但是我们可以根据我们自己的要求重写equals方法。super关键字super“可以看做”是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。使用super调用普通方法语句没有位置限制可以在子类中随便调用。在一个类中若是构造方法的第一行代码没有显式的调用super(…)或者this(…);那么Java默认都会调用super(),含义是调用父类的无参数构造方法。这里的super()可以省略。继承树追溯属性/方法查找顺序(比如查找变量h)查找当前类中有没有属性h依次上溯每个父类查看每个父类中是否有h直到Object如果没找到则出现编译错误。上面步骤只要找到h变量则这个过程终止。构造方法的调用顺序 构造方法的第一句总是super…来调用父类对应的构造方法。所以流程就是先向上追溯到Object然后再依次向下执行类的初始化块和构造方法直到当前子类为止。静态初始化块的调用顺序和构造方法的调用顺序一样不再重复。封装encapsulation封装是面对对象的三大特征之一。对于程序合理的封装让外部调用更加方便更加利于写作。同时对于实现者来说也更加容易修正和修改代码。编程中封装的具体优点1提高代码的安全性2提高代码的复用性3“高内聚”封装细节便于修改内部代码提高可维护性。4“低耦合”简化外部调用便于调用者使用便于扩展和协作。封装的控制符1. private 表示私有只有自己类能访问2. default表示没有修饰符修饰只有同一个包的类能访问3. protected表示可以被同一个包的类以及其他包中的子类访问4. public表示可以被该项目的所有包中的所有类访问封装的属性处理1 一般使用private访问权限2 提供相应的get/set方法来访问相关属性这些方法通常是public修饰的以提供对属性的赋值与读取操作注意boolean变量的get方法是is开头!。3一些只用于本类的辅助性方法可以用private修饰希望其他类调用的方法用public修饰。多态的概念和实现多态指的是同一个方法调用由于对象不同可能会有不同的行为。现实生活中同一个方法具体实现会完全不同。多态的要点多态是方法的多态不是属性的多态多态与属性无关。多态的存在要有3个必要条件继承方法重写父类引用指向子类对象。父类引用指向子类对象后用该父类引用调用子类重写的方法此时多态就出现了。抽象方法和抽象类抽象方法 使用abstract修饰手法没有方法体只有声明。定义的是一种“规范”就是告诉子类必须要给抽象方法提供具体的实现。抽象类 包含抽象方法的类就是抽象类。通过abstract方法定义规范然后要去子类必须定义具体的实现。通过抽象类我们可以做到严格限制子类的设计使子类之间更加通用。抽象类的使用要点有抽象方法的类只能定义成抽象类抽象类不能实例化即不能用new来实例化抽象类。抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例只能用来被子类调用。抽象类只能用来被继承。抽象方法必须被子类实现。接口 interface接口就是规范定义的是一组规则体现了现实世界中“如果你是…则必须能…”的思想。接口的本质是契约就像我们人间的法律一样。制定好后大家都遵守。接口的作用接口就是比“抽象类”还“抽象”的“抽象类”可以更加规范的对子类进行约束。全面地专业地实现了规范和具体实现的分离。从接口的实现者角度看接口定义了可以向外部提供的服务。从接口的调用者角度看接口定义了实现者能提供那些服务。接口是两个模块之间通信的标准通信的规范。如果能把你要设计的模块之间的接口定义好就相当于完成了系统的设计大纲剩下的就是添砖加瓦的具体实现了。大家在工作以后做系统时往往就是使用“面向接口”的思想来设计系统。如何定义和使用接口声明格式[访问修饰符] interface 接口名 [extends 父接口1父接口2…] {常量定义 方法定义}定义接口的详细说明访问修饰符只能是public或默认。接口名和类名采用相同命名机制。extends接口可以多继承。常量接口中的属性只能是常量总是public static final 修饰。不写也是。方法接口中的方法只能是public abstract。 省略的话也是public abstract。字符串String类String类又称作不可变字符序列。String位于java.lang包中Java程序默认导入java.lang包下的所有类。Java字符串就是Unicode字符序列例如字符串“Java”就是4个Unicode字符’J’、’a’、’v’、’a’组成的。Java没有内置的字符串类型而是在标准Java类库中提供了一个预定义的类String每个用双引号括起来的字符串都是String类的一个实例。String类的常用方法以下为string的几个常用的方法。其中我们将其分为辅助类 和 结果类。像ToUpper转大写 ToLower转小写 string.Equals()判断是否相等 Contains()判断是否包含 EndWith() StartsWith()判断以什么开头或者结尾。 IndexOf LastIndexOf()获得以什么开头或者结尾的一个索引。Trim TrimEnd TrimStart 这三个是为了去掉空格来使用的。 这些都可以看做是对字符串的一个辅助作用。在这里插入图片描述