《JavaOOP》第一篇--了解面向对象
Java语言OOP之面向对象
目录
面向对象
面向对象(Object oriented)是一种软件开发的方法,有点为了说明一件事或者一个道理举例说明的意思。
早起的计算机编程是基于面向过程的方法,例如实现算数运算1+1+2=4,通过一个算法就可以解决当时的问题。随着计算机技术的发展,计算机被用于解决越来越复杂的问题。
一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界的关系抽象成类、继承,帮助人们实现对现实世界的抽象和数字建模。通过面向对象的方式,更利于用人理解的方式对复杂的系统进行分析、设计和编程。
为什么使用面向对象
现实世界就是“面向对象的”,任何存在的事物都可以看做“对象”。面向对象就是采用“现实模拟”的方法设计和开发程序,实现了虚拟世界和现实世界的一致性。符合人们的思维习惯,使客户和软件开发人员之间、软件开发人员内部交流更加流畅,同时有代码重用性高、可靠性高等优点。
面向过程的核心是函数,以功能为中心,实现了函数级别的代码重用。
面向对象的核心是封装了属性和方法的类,以数据为中心,实现了类级别的代码重用,面向对象因为采用了类,所以具有继承和多态特性,可以进一步重用代码和简化编程,而面向过程没有继承和多态特定。
面向对象的三大特性:封装、继承、多态。
类的定义和对象的创建
类的概念
面向对象设计的过程就是抽象的过程,分为以下三步来完成:
1.发现类
类主要由属性和行为组成,属性和行为又被称为类的成员变量(或者成员属性)和成员方法,统称为类的成员(除此类的成员还包括构造方法和代码块等等)。
类是对某一事物的描述,是抽象的、概念上的定义。
换种说法,这里的“类”有点“数据类型”中“类型”的意思,就像int类型中包含的是整型数1、2、3……等等他们都有着相同之处,而我们要发现的这个“类”是包含某一事物的,就像人类可以分为黄种人、白种人、黑种人、蓝种人都属于一类就是人;黄种人可以分为中国人、朝鲜人、日本人等等都属于黄种人类。这里的类就好像是由一组具有相同属性和行为组成的集合。
2.发现类的属性
弄明白了类接下来属性就好说了,属性就是类的静态特征,用人类比喻:人类的静态特征有很多姓名、性别、种族、爱好是人类必须要有的特征。
3.发现类的方法
方法就是类的动态特征了,还是用人类比喻:人类的动态特征也有很多会跑、会跳、会动脑子、会吃等等。
搞明白了抽象的过程就必须要知道抽象时遵循的原则是什么:
- 属性和方法的设置是为了解决业务问题
- 关注主要属性和方法
- 如没有必要,勿增加额外的类、属性与方法
前面已经抽象出了类及其属性和方法,下面就该使用代码将它创建出来:
访问修饰符 class 类名{
//属性
//方法
}
this关键字,通常指向当前对象的引用,他可以调用当前对象的成员。
this.属性名; //调用当前对象的属性
this.方法名(); //调用的那个前对象的方法
理解并创建了类就要理解对象的概念了,毕竟是面向对象编程嘛。
对象的概念
对象:用来描述客观事物的一个实体,由一组属性和方法构成。
看起来好像和类差不多?不不不,其实差别很大的。上面我们叫类是抽象的、概念上的定义,而对象是一个实体。对象是一个实体,那么类就是一个模子。类确定了对象将会拥有的特征和行为。
刚开始学习时我还在纠结类既然是概念那我写出来的代码是什么。其实很简单我把类带入现实中比如制造砖块:类就好比制造砖块的模具,而对象就是砖块。用类制造出来的砖块具有模具设定好的尺寸(也就是属性【长、宽、高等等】)和作用(也就是方法【盖房子、铺路等等】)。
总的来说,类是抽象的概念,仅仅是模板。对象是一个你能看得到、摸得着的具体实体。类是对象的类型。对象是特定类型的数据。
单一职责原则
单一职责原则(Single Responsibility Principl缩写SRP),也称为单一功能原则。是面向对象设计中的一个重要原则。
一个类,应该有且只有一个引起变化的原因。在程序设计中,尽量吧不同的职责,放在不同的职责中,即把不同的变化原因,封装在不同的类中。
实例化对象
在具体开发中,必须先定义类再实例化对象(创建对象,也就是使用模具创建实体)。实例化对象的过程分为两部分:
类名 对象名 //声明对象
new 类名() //实例化对象
类名 对象名 = new 类名();
以上就是如何创建对应类的实例,也就是实例化对象。语法中第二个类名加括号被红色标注,与其说是类名不如说是构造方法名,或者说是通过构造方法来创建对象,构造方法的概念后面会讲到。
这里有一个堆和栈的概念:
任何软件在运行时都要在内存中开辟空间,Java虚拟机也是的。JVM在启动时会在自己的内存区域中进行跟细致的划分,因为虚拟机中每一片内存处理的方式都不同,所以要单独进行处理。
JVM内存的划分有五片:寄存器、本地方法区、方法区、栈内存、堆内存。
重点说一下堆和栈:
栈内存存储的都是局部变量(方法外的是全局变量)。都是先加载方法才能进行局部变量的定义,所以是方法先进栈然后定义变量。变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。
堆内存存储的是数据和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(前面讲过对象是一个实体)。实体用于封装多个数据(实体的多个属性)。如果数据消失,这个实体也不会立刻消失。堆是不会随时释放的,但是栈会被立刻释放,堆里的实体虽然不会被立刻释放,但是会被当成垃圾,java有垃圾回收机制不定时的收取。
Demo:
Cat one = new Cat();
Cat two = new Cat();
简单的说,对象实例化是一种引用数据类型。对象实例化就好比是创建一个变量,上面讲了必须先进栈,在栈中声明对象也就是声明变量,但是具体的数据在堆中,new关键字开辟空间的地址就是已经被声明对象的值,这个地址就指向堆中存放数据的空间。
也就是说引用数据类型想操纵数据时,就通过地址而不是直接操纵实体。也就是引用传递时传递的是堆内空间的使用权。
实体在堆内存中产生的每一块空间都会进行默认的初始化,这是堆内存的特点,未初始化的数据是不能用的。但是在堆中可以用,因为初始化过了,但是栈里没有。不同的类型初始值不一样。所以堆和栈里就创建了变量和实体。
那怎么通过对象调用类的属性和方法:
对象名.属性名 = 值; //值的类型是类中属性的类型
对象名.方法名(); //就像上一篇学的方法调用一个道理,只是加了对象名点
对象必须被实例化后才能使用。
使用的方法有很多,比如将类中属性的值赋给另一个同类型变量“数据类型 变量名=对象名.属性名”或者将方法返回的值赋给一个变量。我们要学会变通,多一点尝试就多一点可能。
有一个小问题,当我们在设置性别属性时不希望再次被改变可以使用常量储存。实现的关键字是final,添加在变量数据类型前面。使用常量来存储不变的数据时,在程序运行过程中不会发生变化,只能被引用,不能被重新赋值,也就是只能在定义时修改它的值。
final 数据类型 变量名 = 变量值;
理解结构方法的概念并进行应用
构造方法的名称和类名相同,没有返回值类型,可以指定参数,只能在对象实例化时调用。构造方法的主要作用是在创建对象时执行一些初始化操作。
public 构造方法名(/**可以指定参数*/){
//代码块
}
当没有指定构造方法时,系统会默认自动添加一个无参构造方法。当有指定构造方法时,无论是有参构造还是无参构造系统都不会自动添加无参构造方法。一个类可以有多个构造方法。
构造方法没有返回值,如果有,则不是构造方法,而是和构造方法同名的成员方法。
一般情况我多会自己写一个无参构造方法,避免出现意外。
Demo:
public class Cat{//定义一个猫的类
String name = “花花”;//名字
int month = 3;//年龄
String color = “黄色”;
public Cat(){//这是一个无参构造方法
System.out.println(“我叫”+this.name+”我今年”+this.month+”岁,我是一只”
+this.color+”的猫”);
System.out.println(“我是无参构造方法”);
}
public Cat(String name, int month, String color){
/**这里将获得的参数赋值给本类的属性
*this之前讲过是指向当前对象也就是本类的对象
**/
this.name=name;
this.month=month;
this.color=color;
System.out.println(“我叫”+this.name+”我今年”+this.month+”岁,我是一只”
+this.color+”的猫”);
System.out.println(“我是有参构造方法”);
}
}
public class Test{
public static void main(String[] args){
Cat one = new Cat();
Cat two = new Cat(“小红”,5,”红色”);
}
}
重载
上面说了构造方法可以有多个,但是有个条件就是参数列表不同。
方法名相同,参数列表不同,这称为构造方法的重载,可以通过构造方法的重载来实现多种初始化行为,在创建对象时可以根据需要选择合适的构造方法。方法重载的判断依据如下:
- 必须在同一个类中
- 方法名相同
- 参数列表(放啊参数的个数或参数类型)不同
- 与方法返回值和方法修饰符没有任何关系
新人勿喷,评论多多纠正!!!
上一篇: curl 出现错误的调试方法(必看)
下一篇: PHP静态成员变量