[JAVA学习笔记] 类与对象 - 基础
面向对象编程概念
面向对象编程(OOP),英文全称为Object Oriented Programming,除了OOP(面向对象编程)外,还有OOD(面向对象的设计)、OOA(面向对象的分析)。
在早期的编程语言中,都是以面向过程编程为主,那么面向过程和面向对象又有什么区别?这里我引用什么是面向对象(OOP)一文的一个例子:
有一天你想吃鱼香肉丝了,怎么办呢?你有两个选择:
1、自己买材料,肉,鱼香肉丝调料,蒜苔,胡萝卜等等然后切菜切肉,开炒,盛到盘子里。
2、去饭店,张开嘴:老板!来一份鱼香肉丝!
看出来区别了吗?1是面向过程,2是面向对象。
其实究其根本,面向对象编程最底层也是面向过程编程,只不过我们将某些特定功能抽象成了类(Class),然后对其进行封装,在需要该功能的时候只需要调用这个封装好的类即可。
那么面向对象编程又有什么优势呢?
1、易维护
采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是非常方便和较低成本的。
2、质量高
在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求并具有较高的质量。
3、效率高
在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
4、易扩展
由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。
面向对象编程特性
三大基本特点
- 封装性
也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法。于是开发人员只 需要关注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现 MVC 分工合作,也能有效避免程序间相互依赖,实现代码模块间松藕合。 - 继承性
就是子类自动继承其父级类中的属性和方法,并可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。PHP 只支持单继承,也就是说一个子类只能有一个父类。 - 多态性
子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。于是多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法后却可以获得完全不同的结果,这种技术就是多态性。多态性增强了软件的灵活性。
五大基本原则
- 单一职责原则 SRP (Single Responsibility Principle)
类的功能要单一。 - 开放封闭原则 OCP (Open-Close Principle)
一个模块对于拓展是开放的,对于修改是封闭的。 - 里式替换原则 LSP (the Liskov Substitution Principle LSP)
子类可以替换父类出现在父类能够出现的任何地方。 - 依赖倒置原则 DIP (the Dependency Inversion Principle DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。 - 接口分离原则 ISP (the Interface Segregation Principle ISP)
设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。
Java中的类与对象
基础语法
类 Class
Java中定义一个类的基础语法为:
class TestClass{
...... //类主体
}
需要注意的是,类的命名需要遵循大驼峰原则命名,即每个单词的首字母都需要大写。
public
权限类的定义必须保存在与类名相同的文件中,这个限制不适用于非公共类。
字段 Field
Java类中,字段(field)是变量,字段可以是基本类型,也可以是对象的引用,例如:
class TestClass{
int age = 18; //基本整型
OtherClass name; //OtherClass对象的引用,格式为:<类名> <对象引用>
}
与类的命名不同的是,字段的命名需要遵循小驼峰原则,即第一个单词首字母不大写,其余每个单词首字母都需要大写。
方法 Method
方法(method)定义了一个类的对象(或类的实例)可以执行的动作(功能)。方法包括声明部分和主体部分,声明部分由返回值、方法名、参数列表组成,主体部分则包含了操作执行的代码。
定义方法的基础语法如下:
returnType methodName (ListOfArg){ //声明部分,也称方法签名
...... //主体部分
}
例如:
String getName (String name){ //String表明该方法将返回一个String类型的结果,String name表明该方法需要传入一个Sring类型的变量
return name;
}
OtherClass getAge (int age){ //该方法将会返回一个OtherClass对象,并且需要传入一个int类型的变量
return age;
}
方法的返回类型(Return Type)可以是基本类型(String、int、double等)、对象、void
(为空)。
返回类型为void
则表明该方法不返回任何东西。
main方法
main方法提供了应用程序的入口点,一个java程序应有且仅有一个main方法,JVM通过main方法找到需要启动的运行程序,并且检查main方法所在类是否被java虚拟机装载。如果没有装载,那么就装载该类,并且装载所有相关的其他类。因此程序在运行的时候,第一个执行的方法就是main()方法。通常情况下, 如果要运行一个类的方法,必须首先实例化出来这个类的一个对象,然后通过"对象名.方法名() "的方式来运行方法,但是因为main是程序的入口,这时候还没有实例化对象,因此将main方法声明为static的,这样这个方法就可以直接通过“类名.方法名() ”的方式来调用。
main方法的签名只可为下面的形式:
public static void main(String[] args) {
......
}
关于main方法的更多分析可以阅读详细讲解Java中的main()方法一文。
构造方法
定义:就是类构造对象时调用的方法,主要用来实例化对象。构造方法分为无参构造方法、有参构造方法。
概念:构方法是一种特殊的“成员方法”。
作用:1.构造出来一个类的实例; 2.对构造出来个一个类的实例(对象)初始化
构造方法的名字必须与定义他的类名完全相同,没有返回类型,甚至连void也没有,构造方法主要完成对象的初始化工作,构造方法的调用是在创建一个对象时使用new操作进行的。
类中必定有构造方法,若不写,系统自动添加无参构造方法。接口不允许被实例化,所以接口中没有构造方法。
不能被static
、final
、synchronized
、abstract
和native
修饰
构造方法在初始化对象时自动执行,一般不能显式地直接调用,当同一个类存在多个构造方法时,java编译系统会自动按照初始化时最后面括号的参数个数以及参数类型来自动一一对应完成构造函数的调用。
构造方法可以被重载,没有参数的构造方法称为默认构造方法,与一般的方法一样,构造方法可以进行任何活动,但是经常将他设计为进行各种初始化活动,比如初始化对象的属性。
自定义类中,如果不写构造方法,java系统会默认添加一个无参的构造方法。如果写了一个有参的构造方法,就一定要写无参构造方法。一般情况下,我们自定义的类都要手动给出无参构造方法。
更多内容可参考Java中的构造方法
例如:
public class Person {
String name; //name字段
int age; //age字段
public Person(){ //无参构造方法,命名与类名一致
this.name = "Jack";
this.age = 18;
}
public Person(String name){ //重载 构造方法1(含一个参数name)
this.name = name;
this.age = 18;
}
public Person(String name, int age){ //重载 构造方法2(含两个参数name,age)
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Person mine = new Person(); //创建对象引用mine,此时调用 无参构造方法
Person he = new Person("Lucy"); //创建对象引用he,此时调用构造方法1
Person anybody = new Person("Helen", 3); //创建对象引用anybody,此时调用构造方法2
System.out.println("My name is " + mine.name + " and age is " + mine.age); //输出mine对象的字段
System.out.println("His name is " + he.name + " and age is " + he.age); //输出he对象的字段
System.out.println("Your name is " + anybody.name + " and age is " + anybody.age); //输出anybody的字段
}
}
然后编译并运行这段程序得到:
从这段代码中我们可以明显看出构造方法如下特征:
- 构造方法可以重载,一个类中可以含有多个构造方法(构造器)
- 根据我们创建对象时传入参数列表的不同,会自动调用对用的构造方法
- 构造方法在初始化对象时自动执行
- 如果我们编写了一个含参的构造方法,也要写无参的构造方法
可变参数方法
可变参数方法允许方法带有可变长度的参数列表,即不限定传入参数个数,例如average方法可以计算多个参数的平均值:
public static double average(int... args)
//...表示int参数的传入可以有0个或者多个
下面的例子可以形象的展示出可变参数方法的特点:
public class AverageTest{
public static double average(int... nums){ //将接受的所有参数存入可变数组nums中
int sum = 0;
for (int num: nums) { //遍历数组元素并相加
sum += num;
}
double average = sum/nums.length; //求平均值
return average; //返回结果
}
public static void main(String[] args){
double res1 = average(100, 8080); //传入两个参数
double res2 = average(1, 341, 124); //传入三个参数
System.out.println(res1);
System.out.println(res2);
}
}
运行结果:
创建对象
对象也被称为实例(instance),创建对象也被称为“实例化(instantiate)”。创建Java对象有数种方法,例如创建一个yeGirlfriend对象:
new yeGirlfriend("36D");
我们更多的是创建一个对象并且赋给一个变量,为此我们需要声明与对象类型相同的对象引用,例如:
yeGirlfriend first = new yeGirlfriend("36D"); //创建对象引用first,first是yeGirlfriend类型的对象引用
yeGirlfriend second = new yeGirlfriend(); //创建对象引用second,second也是yeGirlfriend类型的对象引用
second.cup = "24C"; //为second的字段cup赋值
如果我们创建了一个对象引用,但是并没有给他分配对象,那么我们就需要赋一个null
给他:
yeGirlfirend first = null;
访问null变量引用的字段或方法会发生错误。
Java包
Java包的用法和概念类似于其他语言中的命名空间,但是包的命名不能以java
、javax
、sun
开头,将某个类组织到某个包中的方法如下:
package ye.girlfriend
... //类
Java中包名和类的源文件物理位置有关,包名表示目录结构,其中包名中的点代表子文件夹。例如一个名为com.ye.sec.TestMyBlog
的包所对应的物理位置应为com/ye/sec/TestMyBlog.java
[ * ]博客中转载的文章均已标明出处与来源,若无意产生侵权行为深表歉意,需要删除或更改请联系博主: 2245998470[at]qq.com