一,面向对象和面向过程的区别
面向过程:
把事情的步骤一步步实现,然后按顺序调用这些步骤,举个例子,我们去商店买水要几个步骤?
面向过程:
1,我们打开冰箱的门。
2,拿出水。
3,关上冰箱门。
4,付款。
public void openDoor(){} //开门
public void takewater(){} //拿水
public void closeDoor(){} //关门
public void pay(){} //付款
面向对象:
在买水这个过程中有三个对象,一个是人,一个是冰箱,一个是水。
水有一个属性是价格。
人的功能有拿水,付款。
冰箱的功能有开门,关门。
class people{
public void take(水){} //拿水
public void pay(水){} //付款
}
class fridge{
public void open(){} //开门
public void close(){} //关门
}
class water{
int money //价格
}
这里我们可以发现每一个对象之间没有必要的联系,各个对象之间都独立的,有自己的功能和属性,所以一般我们开始创建对象的时候,会先考虑这个对象可能会有什么功能,然后在后期的时候再考虑实现。
面向对象的相对与面向过程更加灵活,就以上面的买水为例子,如果我的水不是从冰箱里拿的了,而是从货架上拿的了,那我们就只需要新建一个货架对象,然后在调用人的take方法时调用货架就行了,但是如果是面向过程的话,我们就要重新写一个人从货架上拿水然后付款的过程了。
二,类和对象之间的关系
对象和类并不是相等,用数学的概念来讲,对象是类的一个子集,是类的具体化。
1,概念
类
类是对一组具有相同属性 特征 行为 功能的对象的定义,它是对象的模板。类的内部封装了属性和方法,用于操作自身的成员。类是对某种对象的定义,具有行为(behavior),它描述一个对象能够做什么以及做的方法(method),它们是可以对这个对象进行操作的程序和过程。
- 类的代码层面:
- 面向对象部分:
- 属性:
- 变量
- 常量 final 修饰 ,必须初始化赋值,且之后不能修改值
- 方法:
- 构造方法 :
- 创建对象时调用 只会执行一次
- 用来初始化执行一部分代码
- 构造代码块 { }:
- 创建对象时调用 用于初始化
- 静态资源部分:属于类 与对象无关 static
- 静态属性:类名可以直接调用 在内存中只存在一份
- 静态方法:类名直接调用 不能使用本类的面向对象成员部分
- 静态代码块:只在类加载时执行一次
对象
对象是由数据(描述事物的属性)和作用于数据的操作(体现事物的行为)组成的封装体,描述客观事物的一个实体,是构成系统的基本单元。简而言之就是一个具体存在的个体。
简单的举一个例子:学生是一个类,小明是一个对象,小明是一个学生。学生作为一个类,它会有年级,班别,文科还是理科各种各样的属性,但是它不会具体规定,因为每个学生的年级,班别,文科还是理科这样的属性都不相同。而小明作为一个对象,一个具体的学生,他就在会年级,班别,文科还是理科上有着具体的属性。所以我们说对象是类的具体化。
类是抽象的,不占用内存,而对象是具体的,占用存储空间。
三,面向对象:封装、继承、接口
1,封装
封装分为两个部分,一个是封,一个是装。
访问修饰权限符:
- public : 公共的 整个项目下都可以使用
- private : 私有的 只能在本类范围内使用
- protected : 同包下 、 不同包的子类范围内可以使用
- 缺省不写: 同包下
- 类只能用public 缺省不写修饰
1,封:将类的成员属性和方法使用受限制的权限修饰符修饰。
2, 从装:使用不受限制的修饰符 定义相关的操作方法 可以操作受限制的属性和方法。
- set&get & 构造方法也可以用来赋值
- 限制了直接给属性赋值的方式 ,数据没有被随意修改的风险
- set方法可以在赋值之前对数据先检查 再赋值
- 实现读写分离
- 格式更加规范
public class User {
// 面向对象成员部分
private String name; //名字
private int age; //年龄
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
我们将属性设为私有,获取和设置属性的方法设为公共的。
这样看似很麻烦,其实有着很大的好处。
比如说我们可以保护一些我们不想被修改的属性,例如我的名字叫小明,这个名字是我爸妈起的,我可不想被人随便修改,那么我们就可以把setName这个方法private(私有化),把getName()这个方法public(公共化)。这样你就只能通过getName这个方法知道我的名字,却不能通过setName修改他了。
还有就是我们可以防止修改属性的时候出现错误,我们可以通过在公用的方法中添加限制条件。例如我要修改年纪,但是很明显年纪不可能是负数,所以我们添加一个条件。
public void setAge(int age) {
if (age < 0) {
System.err.println("输入的年龄不合法~");
return;
}
this.age = age;
}
2,继承
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。Object是所有类的父类
1: 子类继承了父类的什么?
面向对象部分:
-
属性: 继承
-
方法: 继承
-
构造方法: 连带调用子类的构造方法也会调用父类的构造
-
构造代码块: 都会调用
静态资源部分:共用
-
静态属性: 子类可以与父类共用同一个
-
静态方法: 子类名可以直接调用
-
静态代码块:反正只会执行一次
私有的属性和方法会被继承吗? 会
访问权限修饰符只能限制代码可以被使用的范围 ,依然可以通过公共的方法进行操作
2: 方法重写 & 方法重载
-
方法重载: 同一个类中存在多个同名的方法,要求参数、个数、顺序至少有一项不同
-
方法重写: 必须是重写父类的方法,要求参数必须一致,访问权限不能小于父类的
-
一般情况下,整体结构与父类的方法一致,可以修改方法体
-
重写的方法在子类中优先调用 、可以用于子类基于父类方法进行改造 扩展 重构
-
public class Student {
private String name;
public int age;
protected int id;
int score;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Student() { //一个无参数的构造方法
System.out.println("父类构造方法");
}
public Student(int id) { //一个参数为 id 的构造方法(方法重载)
this.id = id;
System.out.println("父类构造方法" + id);
}
protected void read(String book) {
System.out.println("Student read");
}
}
class UNStudent extends Student {
@Override // 重写检查注解
public void read(String book) {
// super.read(book);// 调用父类的方法 super 指代父类引用
System.out.println("UnStudent read");
}
public UNStudent() {
super(10);// 调用父类的构造方法。因为父类中没有空参数构造方法
System.out.println("子类构造方法");
}
public void cet(){
System.out.println("CET");
}
}
3: 转型:(具体的关于向抽象的安全转型)
-
基本数据类型转型:
-
int i=(int)1.2;// 强制转型: 不安全
-
byte b = 120; int i=b;// 自动转型 安全
-
-
引用数据类型转型: 类 接口 数组 对象变量名存储的是对象的引用地址
-
自动转型:
-
小明是一名大学生:
-
小明是一名学生:
-
小明是一个人:
-
-
-
存储小明对象的对象变量名,所存储的地址可以赋值给一个学生对象变量名,也可以赋值给一个人类对象变量名
-
A a = new A();
-
B b = a;
-
C c = b; C c = a; // 其实 a b c 三个变量存储的内容同一个对象的引用地址
-
A extends B // B extends C
-
自动转型之后,父类类型的变量名不能调用子类独有的属性和方法
-
如果调用的是重写的方法呢?即时是父类类型变量名(转型之后)依然调用子类重写的
-
-
强制转型: 不安全 需要在转型之前验明类型
3,接口
-
接口中的属性是默认静态常量
-
接口中的方法默认抽象方法 没有方法体 ,一个类实现接口的时候必须重写所有的抽象方法
一个类实现一个接口 相当于继承这个接口。
interface Lock{//一个叫lock的接口
void open();//抽象方法
void close();//抽象方法
}
public class KeyLock implements Lock{//继承这个接口
@Override // 重写检查注解
void open(){
System.out.println("开门");
}
@Override // 重写检查注解
void close(){
System.out.println("关门");
}
}