面向对象基础
一、面向对象基本内容
1、什么是面向对象编程
面向对象编程(Object-Oriented Programming , OOP)
面向对象编程的本质:以类的方式组织代码,以对象的组织(封装)数据
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后有对象。类是对象的模板
2、面向对象与面向过程区别
面向过程:
步骤清晰简单,第一步做什么,第二步做什么…
面对过程适合处理一些较为简单的问题
面向对象:
物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
形象描述:(装修房子)
面向对象:粉刷、铺地、搬家具
面向过程:搬家具—>沙发,衣柜,洗衣机等等详细到每一个步骤
总结:
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理
二、类与对象
1、类
类是描述对象的“基本原型”,它定义一类对象所能拥有的数据和能完成的操作。在面向对象的程序设计中,类是程序的基本单元。
相似的对象可以归并到同一个类中去,就像传统语言中的变量与类型关系一样。
程序中的对象是类的一个实例,是一个软件单元,它由一组结构化的数据和在其上的一组操作构成。
①类的组成
变量:指对象的状态。
方法:指对象的功能单元。
消息:软件对象通过相互间传递消息来相互作用和通信,一个消息由三部分组成
②类变量(静态变量)
类变量:使用static修饰符
类变量是对象间共享属性,如下:
当使用static修饰时,该类的存储空间将发生变化,产生共享区。所有对象共享一个static修饰的属性。一个对象对类变量进行修改时,其他对象的该类变量也跟着变化。
2、对象
可以将现实生活中的对象经过抽象,映射为程序中的对象。对象在程序中是通过一种抽象数据类型来描述的,这种抽象数据类型称为类(class)。
必须声明该类类型的一个变量,这个变量没有定义一个对象。实际上,它只是一个能够引用对象的简单变量。
该声明要创建一个对象的实际的物理拷贝,并把对于该对象的引用赋给该变量。
3、类与对象的关系
类(class)和对象(object)是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型。
类是Java的核心和本质。它是Java语言的基础,因为类定义了对象的本质。类定义了一种新的数据类型,可以用新类型来创建该类型的对象。
它们的关系是,对象是类的实例,类是对象的模板。对象是通过new classname产生的,用来调用类的方法;类的构造方法 。
类就是拥有相等功能和相同的属性的对象的集合 – 抽象的
对象就是类的实例 – 具体类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。(动物、植物、手机、电脑…)
Person类、Pat类、Car类等,这些类都是用来描述/定义某一类具体事物应该具备的特点和行为
对象是抽象概念的具体实例
张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例
能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念
三、创建与初始化对象
使用new关键字创建对象,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
1、必须和类的名字相同
2、必须没有返回值类型,也不能写void
1、默认初始化
2、多对象声明与创建
xm和xh都是Student类的实例,具有相同的属性
3、类加载与对象创建初始化过程
①类加载
类加载的时间点要早于对象创建的时间点
类加载:发生在类第一次被虚拟机调用,类会被虚拟机加载,一般来说类只被加载一次
类加载要完成的操作:
Ⅰ、初始化类变量;Ⅱ、分配类方法的函数入口;Ⅲ、执行静态块
package com.goktech.testDemo;
public class Person {
/**
* static是伴随类的加载而开始出现,因此只有static修饰的才被加载
*/
static String country = "china";//初始化类变量
String name;
int age;
double height;
public Person(){
System.out.println("执行构造函数");//对象没有创建的时候,构造函数不会执行
}
static {
System.out.println("执行了静态块");//静态块一般只执行一次
}
{
System.out.println("执行对象块");//对象没有创建的时候,对象块不会执行。对象块每次
}
public void eat(){
System.out.println("吃");
}
public static void run(){//分配类方法的函数入口
System.out.println("跑");
}
public static void main(String[] args) {//分配类方法的函数入口
//类加载的时候,只是为方法开辟了存储空间,并不会运行方法中的语句
//即使将主函数放到类的最前面,运行结果依然如下
System.out.println("程序开始");
//静态只能访问静态
//System.out.println(name);//错误
System.out.println(country);
//eat();//错误
run();
System.out.println("程序结束");
}
}
②对象创建
对象创建晚于类加载的时间
对象创建要完成的操作:
Ⅰ、初始化实例变量;Ⅱ、分配实例方法的函数入口;Ⅲ、执行对象块;Ⅳ、执行构造函数(super();剩余语句才是第四部分执行)
三、构造方法(构造器)
如果一个类中没用定义构造方法,那么会有一个默认的构造
这个构造是空参,且空实现
public Student(){//构造方法用于设定类的初始值
}//默认构造参数,格式如上,不需要写返回值类型
四、修饰词private
private: 私有的,权限修饰符,可以修饰成员变量和成员方法。被private修饰的成员只能在本类中访问。
当类中定义有私有数据,需要定义set和get方法,让外部类调用idea自动生成set和get:鼠标右键编辑器,选择“Generate”,也可以直接按Alt+Insert快捷键,选择Getter和Setter进行分别生成get/set方法
五、this.作用
this的作用,可以区分是对象的属性,还是形参
this后面对象属性,等号后面是形式参数
六、值传递和引用传递
值传递:基本数据类型采用值传递;
实参的值永远不发生变化
引用传递:类类型采用引用传递;
实参的内存地址不变化,但是内容有可能变化
1、值传递
Java的main方法调用其他方法时,将值传递给b方法,b方法进行一些列操作并没有返回值,因此a的值并没有改变。
2、引用传递
public class Demo06 {
//引用传递,本质还是值传递
public static void main(String[] args) {
Perosn perosn = new Perosn();
System.out.println(perosn.name);
Demo06.change(perosn);
System.out.println(perosn.name);
}
public static void change(Perosn perosn) {
//perosn是一个对象:指向的--->Perosn perosn = new Perosn();这是一个具体的类,可以改变属性
perosn.name = "GOK";
}
}
//定义了一个Perosn类,有一个属性:name
class Perosn{
String name;
}
七、常见异常
空指针异常
只是声明了一个变量(可以理解为一个索引名或者指针名字),但是这个变量没有指向任何实质的对象,因为根本没有创建对象,没有对象的话,就是默认值null了;因此发生了空指针异常。
八、对象消亡 垃圾回收机制
内存释放:Java使用自动的处理重新分配内存的方法,即垃圾回收机制:当一个对象的引用不存在,则该对象被认为是不再需要的,它所占有的内存会被释放掉。
JAVA自动回收垃圾,不需要开发人员自己控制。
如果想强制垃圾回收,可以调用System.gc();
重写Object类的finalize()方法:主要用来释放非java资源,例如文件句柄或window字体字符
方法原型来自父类Object提供的方法:
protected void finalize(){
//finalization code here
}当对象被释放时,将自动调用对象的finalize()方法
public class Test05GC {
//内存释放:
//Java使用自动的处理重新分配内存的方法:
//垃圾回收:当一个对象的引用不存在,则该对象被认为是不再需要的,
//它所占有的内存会被释放掉。
// java自动回收无用对象的内存空间,不需要程序员来控制.
// System.gc() 运行垃圾回收器。// 以便能够快速地重用这些对象当前占用的内存。
// 调用 System.gc()暗示着 Java 虚拟机做了一些努力来回收未用对象。
// 当控制权从方法调用中返回时,虚拟机已经尽最大努力从所有丢弃的对象中回收了空间。
//隐式调用对象finalize(),重写自Object父类中的方法
protected void finalize() throws Throwable {
// TODO Auto-generated method stub
super.finalize();
System.out.println("对象被回收了 finalize() this="+this);
}
九、访问权限
封装将数据和处理数据的代码连接起来。同时封装提供另一个重要属性:访问控制。通过访问控制,可以阻止对象的滥用。
通过访问指示符来限制访问范围。
当一个类可以被访问时,对类内的成员变量和成员方法而言,其应用范围可以通过施以一定的访问权限来限定。
public class Person {
private int id;//只用在本类中
String name;//本类或者同包不同类中
protected double height;//本类或者同包不同类中(若有继承关系,也可在任意包中的类都可使用)
public char sex;//任意包中的类都可使用
}
public: 任何其它类、对象只要可以看到这个类的话,那么它就可以存取变量的数据,或使用方法。
protected:同一类,同一包可以使用。有继承关系后,不同包的类要使用,必须是该类的子类。
private:不允许任何其他类存取和调用。
public class Person {
private int id;//只用在本类中
String name;//本类或者同包不同类中
protected double height;//本类或者同包不同类中(若有继承关系,也可在任意包中的类都可使用)
public char sex;//任意包中的类都可使用
}
public: 任何其它类、对象只要可以看到这个类的话,那么它就可以存取变量的数据,或使用方法。
protected:同一类,同一包可以使用。有继承关系后,不同包的类要使用,必须是该类的子类。
private:不允许任何其他类存取和调用。
(默认,前边没有修饰字的情况):在同一程序包中出现的类才可以直接使用它的数据和方法.