类与对象
面向对象简介
C是面向过程的,c++、java是面向对象的;
面向过程:面对个问题的解决方案,更多的情况下不会做出重用的设计;
面向对象:模块化设计且可重用配置,更多情况下考虑是的标准的模块化设计,在使用时根据标准进行拼装。
三个主要特征:
- 封装性:内部的操作对外部而言不可见,内部的操作不可直接使用的时候才是安全的;
- 继承性:在已有结构的基础上进行功能的扩充;
- 多态性;是在继承性的基础上扩充而来的概念,指的是类型的转换处理;
面向对象开发的三个过程:
- OOA:面向对象分析;
- OOD:面向对象设计;
- OOP:面向对象编程;
类与对象简介
类:对某一类事务的共性的抽象概念,而对象描述的是一个具体的产物;
每一个属性的集合就构成一个对象的定义,而群体的定义构成了类;
eg:类是一个模块,对象是类可以使用的一个实例;
在类之中会有两个组成:
- 成员属性(Field):属性;
- 操作方法(Method):定义对象具有的处理行为;
注: 对象的使用不能超过类的定义
类与对象的具体定义
Java中类是一个独立的结构体,使用class来定义,类中由属性和方法组成。
范例:
class Person{
String name; //定义一个类
int age;
public void tell(){
System.out.printlb("姓名:"+name+" 年龄"+age)
}
}
两个属性一个方法,如果要使用类,必须使用对象来完成,使用如下:
- 声明并实例化对象:类名称 对象名称 = new 类名称();
- 分步骤:
- 声明对象:类对象 对象名称 = null;
- 实例化对象:对象名称 = new 类名称();
注: 如果程序并没有进行对象属性内容的设置,则改数据内容为其对应数据类型的默认值;
对象内存分析
对象实例化操作初步分析
引用数据类型最大的困难之处在于要进行内存的管理,
两块对位常用的内存分 析:
- 堆内存:保存的是对象的具体信息,程序中堆内存空间的开辟是通过new完成的;
- 栈内存:保存的是一块堆内存的地址,通过地址找到对应的堆内存,而后找到对象内容,可简单理解为对象的名称保存在栈内存中;
内存分析
- 声明并实例化对象
Person per = new Person()
程序看到new开辟新的堆内存,*Person()*决定了堆内存保存的内容;
per为栈内存中保存的内存地址;
per.name="test"
改变堆内存中的数据; - 分步骤
Person per = null; //实例化对象
per = new Person(); // 开辟空间
per.name="test" //赋值
注: 所有的对象在调用类中的属性或方法是必须要实例化完成后才可以执行;
NullPointerExeption: 空指向异常,未在堆内存中开辟空间产生的问题,且只有引用数据类型会产生此问题;
对象引用分析
引用传递的本质:同一块堆内存空间可以被不同的栈内存指向,也可以更换指向;
范例:
Person per1 = new Person(); // new开辟新的空间
Person per2 = per1; //引用传递:per2与per1指向同一堆空间
per2.age = 80; //per1.age的值也为80
注: 引用传递可以发生在方法上,一定要观察方法的参数类型,同时也要观察方法的执行过程
引用与垃圾产生分析
对于引用传递引用不当会造成垃圾的产生,简单分析
Person per1 = new Person();
Person per2 = new Person();
per1.name ="key";
per1.age = 18;
per2.name = "key_2";
per2.age = 19;
per2 = per1; //引用传递,将per1的内存地址传递给per1,而per2指向的堆空间成为垃圾;
per2.age = 80; //则per1.age = 80
分析:开辟了两块堆空间
垃圾: 没有任何栈内存指向的对内存空间,所有的垃圾将被GC(Garbage Collector垃圾收集器)不定期进行回收并且释放内存空间,垃圾过多影响性能;
一个栈内存只能保存一个堆内存的地址数据,若发生更改,则之前的地址数据将从栈内存中彻底消失。
深度分析类与对象
方法一般是对外提供服务的,不会进行封装处理;属性需要较高的安全性,采用封装性对属性进行保护;
默认情况下,对类中的属性可以通过其他类利用对象进行调用;
对属性进行封装;
class Person(){
private String name; // 封装
}
属性一旦封装后外部不能够直接访问,即对外部不可见,但是对类的内部是可见的,那么如果想要外部访问封装的属性,在Java开发标准中有如下要求:
- 设置或取得属性使用[方法 setXxx(),getXxx()]
- 设置属性在类的内部进行:public
- 获取属性也调用类内部的方法:public
注: 类中的所有(大部分)属性都必须使用private封装,且必须提供setter、getter方法;
构造方法与匿名对象
现在的程序在使用类是按照如下步骤进行:
- 声明并实例化对象
- 通过一系列的setter方法类中的属性设置内容
但假设类中的属性有很多,则调用setter比较麻烦,考虑到对象的初始化问题,专门提供构造方法,提供属性初始化使用,只有在关键字new时;
在java中构造方法定义:
- 构造方法名称必须与类名称保持一致;
- 构造方法不允许设置任何类型的返回值,即:没有返回值定义;
- 构造方法是在使用关键字new实例化对象的时候自动调用的;
class Person{
// 方法名与类名称相同,无返回值定义
public Person(String n,int a){ //有参构造
name = n;
age = a;
}
}
针对于当前的对象实例化格式与之前的对象实例化格式比较:
- 之前的:Person per = new Person();
- 现在的:Person per = new Person(“A”,18);
若类中没有定义构造方法,那么会默认有一个无参的,什么都不做的构造方法,这个构造方法是在程序编译时自动创建的。
为什么构造方法不允许定义返回值类型?
既然构造方法不返回数据,为什么不适用void定义?
编译器是根据代码结构进行编译处理的,若使用void编写,次结构与普通方法完全相同,编译器无法区分。
构造方法是在类对象实例化的时候调用的,而普通方法是在类对象实例化产生后调用的
既然构造方法本身是一个方法,那么方法就具有重载的特点,构造方法重载的时候只需要考虑参数的类型与个数;
再进行多个构造方法定义的时候强烈建议有一些定义的顺序,可以按照参数的个数排列;
构造方法是在类对象实例化的时候调用的,而setter具有修改数据的功能;
匿名对象:
new Person("A",10);
由于此对象没有任何的引用,所有该对象使用一次后便成为垃圾,会被GC回收与释放;
的时候强烈建议有一些定义的顺序,可以按照参数的个数排列;
构造方法是在类对象实例化的时候调用的,而setter具有修改数据的功能;
匿名对象:
new Person("A",10);
由于此对象没有任何的引用,所有该对象使用一次后便成为垃圾,会被GC回收与释放;
注: 只要是方法都可以传递任意的数据类型(基本数据类型,引用数据类型)