1 什么是面向对象?
面向对象(Oriented Object)程序设计是当今主流的程序设计模型,简称OOP。是一种对现实世界理解和抽象的方法。面向过程(Procedure Oriented)是一种以过程为中心的编程思想,以什么正在发生为主要目标进行编程,不同于面向对对象是谁在受影响。与面向对象明显的不同就是封装、继承、类。
1.1 类和对象
**类(Class)**是构造对象的模板,由类构造对象的过程称为类的实例。类相当于我们生活中具有共同特征的一类事物,诸如书、窗户、计算机。
生活中我们接触的所有东西都可以被称作为一个对象。比如你正在使用的浏览这篇文章的电子设备、你手边正在被你使用的那个鼠标、我正在敲的键盘等,全都是对象。对象不是一个笼统的,类似于“桌子”、“椅子”这种代表一类事物的概念,而是类似于“那张桌子”、“这把椅子”这样的具体的某一个事物。这就是对象。
2 预定义类和用户自定义类
2.1 预定义类
在Java里面没有类就无法做任何事情,然而并不是所有类都具有面向对象的特征。预定义是指,已经定义好的类,例如String,Integer等等;
2.12用户自定义类
在上一篇文章中,我编写了一些简单的类,但是只包含了一个简单的main方法。而我们开始设计复杂应用程序所需要的各种主力类,通常这些类是没有main方法,却有自己的实例域和实例方法。
- 用于描述一种数据类型。
- 在Java中,通过新建类来描述各种自定义的数据类型。
- 一个类中可以是若干基本类型的组合
public class Student { public String id; public String name; public boolean sex; public String cellphone; //类型名 Student,它表示一个自定义的类型 //属性(Property):id, name, sex, cellphone } public class xxx { public static void main(String[] args) { Student stu=new Student; stu.name="小王"; } } //new Student: 创建一个Student类型的对象 //s1.id : 对象的属性用点号来访问
2.3 隐式参数与显示参数
定义如下:
- 显示参数:在方法中明确定义的参数为显示参数
- 隐式参数:未在方法中定义,但的确又动态影响到程序运行的“参数”
并在类的方法中调用了类的实例域。
public void setAge(String age) { this.age=age; } Student stu=new Student; stu.setAge(20); /** 通过使用setName方法设置姓名,出现在方法名前的Student生成对象为隐式参数 方法名后面括号内的数值,则为显示参数 */
2.4 封装的优点
封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式,简单的来说就是我将不想给别人看的数据,以及别人无需知道的内部细节, “锁起来” ,我们只留下一些入口,使其与外部发生联系。
2.5 final实例域
可以将实例域定义为final,在对象创建之后 ,final作为java的关键字,它可以修饰类,方法,变量及参数。
1) 类:当final修饰一个类时,表明其为最终类,它不能被继承,并且类中所有的属性和方法都默认是final类型,如String,Integer等包装类均为final类。
2)方法:被final修饰的方法不可被重写。它可以防止任何继承类修改方法的意义和实现,而且,使用final修饰方法的执行效率一般高于普通方法。
3 构造器
3.1 初始构造器
- 构造器与类同名,构造类的对象时,构造器会运行,以便将实例域初始化所希望的状态。
- 构造器与类同名
- 每个类可以有1个以上的构造器
- 构造器可以有0个或1个或多个参数
- 构造器没有返回值
- 构造器总是伴随着new操作一起调用
public Student(String name,int age) { this.name=name; this.age=age; } new Student("Daniel",15,);
3.2 重载
如果多个方法有相同的名字、不同的参数,便产生了重载。编译器必须挑选出具体执行哪个方法,它通过用各个方法给出的参数类型与特定方法调用所使用得值类型进行匹配来挑选出相应的方法。
//之前使用过的StringBuilder, StringBuilder message=new StringBuilder(); //或者直接进行初始化 StringBuilder message=new StringBuilder("This is a String test!");
3.2.1 无参构造
很多类都包含一个无参数的构造函数,对象由无参数构造函数创建时,其状态会设置为适当的默认值。如果编写一个类时没有编写构造器,那么系统就会提供一个无参构造器。
3.2.2 参数名
在编写很小的构造器时,常常在参数命名上出现错误。
public Student(Stirng n,int a) { name=n; age=a; } //这样做存在缺陷,只有阅读代码才能了解参数n和a的含义。
**解决小技巧:**参数变量用同样的名字将实例域屏蔽起来。可以采用this.xxx的形式来访问实例域。这里的this指示隐式参数,也就是所构造的对象。
4 静态域与静态方法
在前面的简单示例中,main方法都被标记为static修饰符,本节讨论一下这个修饰符的含义。
4.1 静态域
如果将域定义为static,每个类只有一个这样的域。而每一个对象对于所有的实例域却都有自己的一份拷贝。
class Employee { private static int nextId=1; private int id; }
上面的例子说明每一个雇员对象都有一个自己的id域,但这个类的所有实例将共享一个nextId域。换句话说,如果有10个对象,则有10个实例域id,但只有一个静态域nextId域。即使是没有雇员对象,nextId也存在。
4.2 静态常量
静态变量使用比较少,但静态常量却用得较多。例如,在Math类中定义了一个静态常量:
public class Math { public static final double PI=3.14159265358979323846 }
4.3 静态方法
静态方法是一种不能向对象实施操作的方法。例如,Math类的pow方法就是一个静态方法。表达式Math.pow(x,a)
在运算时,不适用任何Math对象,也就是说没有隐式参数。
4.4 方法参数
按值调用表示的方法接收的是调用者提供的值,而按引用调用表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。Java采用按值调用,即方法得到的是所有参数值的一个拷贝,方法不能修改传递给它的任何参数变量的内容。
大体上说,两种调用的根本并不在于传递的是值还是地址(毕竟地址也是一个值),而是在于形参和实参是否占用同一块内存空间,详细参考链接。
5 包
为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
为了保证包名的绝对唯一性,Sun公司建议将公司的因特网域名以逆序的形式作为包名,并且对弈不同的项目使用不同的子包。
java.time.LocalDate today=java.time.LocalDate.now(); /** 若采用这种方式很繁琐,更简单且更常用的方式是使用import语句。 /
参考链接
1、什么是面向对象
2、有关Java方法参数是引用调用还是值调用的问题