面向对象
“面向对象”(Object Oriented)是一种以对象为中心的编程思想,简称 OO。
1.面向过程和面向对象区别
(1)面向过程:
- 注重步骤,注重的是实现这个功能的步骤。第一步干什么,第二步干什么。
- 注重实现功能的因果关系。因为A所有B,因为B所以C。
- 缺点:耦合度高,扩展力差。耦合度就是黏连程度,代码和代码之间因为因果关系结合在一起,假设其中任何一个因果关系出现问题,此时整个系统的运转都会出现问题。
- 优点:对于小型项目(功能),采用面向过程的方式进行开发,效率较高。不需要前期进行对象的提取,模型的建立。
(2)面向对象:
- 面向对象能有效提高编程的效率,通过封装技术,可以像搭积木的一样快速开发出一个全新的系统。面向对象将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。比如:对象“张三”,对象“书本”,对象“黑笔”,对象“教室”,然后将以上的4个对象组合在一起,就可以模拟一个人的学习场景。
- 用例子形容就是,假如一个电脑所有配件都组合在一起,是个一体机,一个部位坏了整个都需要修,那么他就是面向过程。但是如果将内存条、主板、CPU、硬盘等每个配件都看作对象,组装在一起,形成一台计算机,其中一个坏了只需要修一个部位,这就是面向对象。
2.使用面向对象编程思想开发系统,一般包括:OOA/OOD/OOP
- ① OOA:面向对象分析(Object-Oriented Analysis)
- ② OOD:面向对象设计(Object-Oriented Design)
- ③ OOP:面向对象编程(Object-Oriented Programming)
3.面向对象包括三大特征:封装、继承、多态。
4.类和对象的概念
- 类是现实世界当中具有共同特征的事物进行抽象形成的模板或概念。如"文具"。
- 对象是实际存在的个体。如铅笔、橡皮、钢笔。
- 类可以创建对象,对象又被称为实例(instance),这个过程也可以称为实例化。
- 类 -- 实例化 -- > 对象(实例)
- 对象 -- 抽象 -- > 类
5.类 = 属性 + 方法
定义一个类的语法格式:
[修饰符列表] class 类名 {
属性(变量,描述状态);
方法(描述动作/行为);
}注:修饰符列表可以省略
可以定义一个学生类(Student)
public class Student {
// 属性:姓名 性别 年龄
String name;
int age;
boolean gender;
// 方法
public static void main(String[] args){//主方法
}
public .... sing(){
}
public .... dance(){
}
public .... study(){
}
}
对象的创建和使用
创建对象语法:类名 变量名 = new 类名();
语法解释:
- new 类名()是一个对象。
- 通过一个类,是可以创建N多个对象的。
- new是一个运算符,专门负责对象的创建。
例子1:①首先创建一个学生类Student.java
public class Student{ // 这个程序编译之后,会生成Student.class字节码文件。
// 属性:学号,姓名,年龄,性别,地址
// 方法体外,类体内定义的变量叫做:成员变量。对于成员变量来说,没有手动赋值时,系统默认赋值。
// 学号(成员变量)
int no; //这种成员变量又被称为“实例变量”,一个对象一份。
// 姓名
String name;
// 年龄
int age;
// 性别
boolean gender;
// 住址
String addr;
}
其中,Student既是一个类名,同时又是一个“类型名”,属于引用数据类型。
数据类型包括两种:
- 基本数据类型:byte short int long float double boolean char
- 引用数据类型:String、Student.....(java中所有的“类”都属于引用数据类型。)
②然后创建对象StudentTest.java
public class StudentTest{
public static void main(String[] args){
int i = 100;
// 创建一个对象 s1这个局部变量叫做引用
Student s1 = new Student();
// 再通过该类创建一个全新的对象 s2也叫做引用
Student s2 = new Student();
// 访问学生1实例变量。语法:引用.实例变量名
System.out.println(s1.no);
System.out.println(s1.name);
System.out.println(s1.age);
System.out.println(s1.sex);
System.out.println(s1.addr);
System.out.println("-----------------------------");
// 访问学生2实例变量
System.out.println(s2.no);
System.out.println(s2.name);
System.out.println(s2.age);
System.out.println(s2.sex);
System.out.println(s2.addr);
// 修改内存中实例变量的值。
s1.no = 110;
s1.name = "张三";
s1.age = 20;
System.out.println("学号=" + s1.no);
System.out.println("姓名=" + s1.name);
System.out.println("年龄=" + s1.age);
}
}
// 以上的这个程序就相当于通过Student类实例化了2个Student对象。
// 创建对象的个数没有限制,可以随意。只要有模板类就行。
// 2个对象都属于学生类型。
语法解释:
- 创建对象就和普通的 int i = 100 一个道理。
- s1是变量名(s1不能叫做对象。s1只是一个变量名字。)
- Student是变量s1的数据类型(引用数据类型)
- new Student() 这是一个对象。(学生类创建出来的学生对象。)
关于编译:
- ①先编译Student.java,然后再编译StudentTest.java
- ②直接编译StudentTest.java。对于编译器来说,编译StudentTest.java文件的时候,会自动找Student.class,如果没有,会自动编译Student.java文件,生成Student.class文件。
JVM中存储空间:
- 栈:方法调用,存储局部变量,以及指向对象的内存地址。s1,s2是局部变量,又叫引用。该变量中保存值的内存地址指向了堆内存当中的对象。
- 堆内存:存储对象,以及对象的实例变量。new Student()就是对象,no、age、name等是实例变量,实例变量都在堆内存的对象内部。
- 方法区:存储代码片段,代码字节码.class。
例子2:通过创建对象引用地址和用户类
①Address.java
// 住址类
public class Address{
// 一个家庭住址有3个属性。
// 城市
String city; // 实例变量
// 街道
String street;
// 邮编
String zipcode;
}
②User.java
//用户类
public class User{
// 以下3个都是属性,都是实例变量。(对象变量。)
// 用户id
int id; // int是一种基本数据类型,id是实例变量
// 用户名
String username; // String是一种引用数据类型,username是实例变量
// 家庭住址
Address addr; //ddress是一种引用数据类型,addr是一个引用,addr是成员变量并且还是一个实例变量。
}
③Test.java
public class Test{
public static void main(String[] args){
//没创建对象前,不能访问类中的变量
//System.out.println(User.id);//报错了。id是实例变量,必须先创建对象,通过“引用.”的方式访问。
//正确如下:
//User u = new User(); //u是引用。
//System.out.println(User.id);
// 家庭住址对象
Address a = new Address(); //a是引用
a.city = "南京";
a.street = "秦淮区";
a.zipcode = "210001";
// 用户对象
User u = new User();
System.out.println(u.id); // 0
System.out.println(u.username); // null
System.out.println(u.addr); // null
u.id = 11111;
u.username = "zhangsan";
u.addr = a; //将a变量中的内存地址赋值给addr
//-----------------------上句代码解释---------------------------
// Address k = new Address(); // Address k = 0x1111; 0x1111是地址
// Address m = k; // 这里表示将k变量中保存的0x1111复制了一份传给了m变量。
// 输出zhangsan和他的城市
System.out.println(u.username + "是"+u.addr.city+"城市的!");
// u.addr.city 这行代码可拆分,拆分成以下代码和以上效果完全相同,原理完全相同。
Address ad = u.addr; // addr是address类型
String zhuZhi = ad.city; // city是String类型
System.out.println(zhuZhi);
}
}
引用和对象的区分:
- “引用”是存储对象内存地址的一个变量。引用不一定是局部变量。
- “对象”是堆里new出来的。