面向对象
面向对象 vs 面向过程
- 面向过程
- 步骤清晰简单,第一步做什么,第二部做什么….
- 面向过程适合处理一些较为简单的问题
- 面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要那些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的探索。
- 面向对象适合处理复杂问题,适合处理需要多人协作的问题。
- 面向对象变成(Object-Oriented Programming, OOP)
- 面向对象变成的本质就是:以类的组织方式代码,以对象的组织(封装)数据
- 抽象
- 三大特性
- 封装
- 继承
- 多态
- 从认识论的角度考虑现有对象后有类。对象,是具体的食物。类,是抽象的,是对对象的抽象
-
方法调用
static 与类同时加载,而非static 在类实例化之后加载,因此非static无法被直接引用,需要通过new进行实例化
值传递
package com.java.Object;
public class Value {
public static void main(String[] args) {
int a =1;
System.out.println(a); // 1
change(a);
System.out.println(a); // 1
}
public static void change(int a) {
a = 10;
// return a;
}
}
package com.java.Object;
// 对象,内存
// 引用传递: 对象,本质还是值传递
public class ObjValue {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name); // null\
change(person);
System.out.println(person.name); // xiaoyi
}
public static void change(Person person) {
// person是一个对象; 它指向的是Person的实例
person.name = "xiaoyi";
}
}
// 定义一个Person类 有一个属性:name
class Person {
String name; // 默认值为null
}
类与对象的关系
- 类是一种抽象的数据类型,它是对一类事物整体描述/定义,但并不能代表某一个具体的事物
- 动物、植物、手机、电脑…
- Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体事物应该具备的特点和行为
对象是抽象概念的具体实例
使用new关键字创建对象
- 使用new关键字创建对象的时候,除了分配内存空间之外,还会给创建好的对象 进行默认的初始化以及对类中的构造器调用
- 类中的构造器也称为构造方法,是在进行创建对象的时候必须调用的。并且构造器有以下两个特点:
- 必须和类的名字相同
- 必须没有返回值,也不能写void
- 构造器必须要掌握 ```java package com.xy.app;
public class Appliction { public static void main(String[] args) { // 类: 抽象的,需要实例化 // 类实例化之后会返回一个自己的对象 // student 对象就是一个Student类的具体事例 Student student = new Student(); student.name = “xyz”; student.age = 30; System.out.println(student.name); // xyz System.out.println(student.age); // 30
Student xiaoming = new Student();
System.out.println(xiaoming.age);// 0
System.out.println(xiaoming.name);// null
}
}
<a name="FxA4g"></a>
#### 构造器
- 用来初始化
- 一个类即使什么都不写,也会存在一个方法
- 构造器也可以重载,根据传不传参数调用不同的构造器
- "alt + insert"快速生成构造器(Idea)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/13002623/1650717561256-d8574faf-3ce2-4150-81fe-56f1b63df223.png#clientId=ua3d50358-7966-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=308&id=u15605a56&margin=%5Bobject%20Object%5D&name=image.png&originHeight=774&originWidth=1855&originalType=binary&ratio=1&rotation=0&showTitle=false&size=45664&status=done&style=none&taskId=ua160e847-7425-4be4-9c97-ec2803d2a81&title=&width=737)
```java
package com.xy.app;
// java文件 ---> class文件
public class Person {
String name;
// 一个显式定义的构造器
// 实例化初始值
// 使用new 关键字,本质是在调用构造器
public Person() {
this.name = "xyz";
}
}
--------------------
// 实例化
Person person = new Person();
package com.xy.app;
// java文件 ---> class文件
public class Person {
String name;
public Person(String name) {
this.name = name;
}
}
-----------------------------
// 实例化
Person person = new Person("张飞");
实例化对象的内存调用
封装
- 该露的露,该藏的藏
- 程序设计追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部
- 封装(数据的隐藏)
- 通常,应该禁止访问一个对象中的实际表示,而应通过接口来访问,这成为信息隐藏。
- 记住:属性私有,get/set ```java package com.xy.app;
public class Teacher { private String name; private int age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age > 120) {
this.age = 0;
}else if(age <= 0) {
this.age = 0;
}
this.age = age;
}
}
package com.xy.app;
public class Appliction { public static void main(String[] args) { Teacher teacher = new Teacher(); teacher.getName(); teacher.setName(“张山”); teacher.setAge(999); //防止不合法的年龄 } }
<a name="k05mK"></a>
### 继承
- 继承的本质是对某一批对象的抽象,从而实现对现实世界更好的建模
- extends的意思是扩展。子类就是父类的扩展
- Java中只有单类继承,没有多类继承
- 继承是类和类的一种关系。除此之外类和类之间的关系还有依赖、组合、聚合等。
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
1. object类
![image.png](https://cdn.nlark.com/yuque/0/2022/png/13002623/1650721177889-ce533148-d5a2-4051-8fdc-31545fc60e2b.png#clientId=u307d0e74-2c27-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=820&id=udd44b5b9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1230&originWidth=2530&originalType=binary&ratio=1&rotation=0&showTitle=false&size=172690&status=done&style=none&taskId=u0dab244f-4faf-4685-aaa5-b3cb727781f&title=&width=1686.6666666666667)
2. super
1. super调用父类的构造方法,必须在构造方法的第一个
2. super必须只能出现在子类的方法或构造函数中
3. super和this不能同时调用构造方法
4. this:本身调用这个对象;super:代表父类对象的应用
![image.png](https://cdn.nlark.com/yuque/0/2022/png/13002623/1650721760979-47cdc0eb-dbce-4646-9b0c-78b80a8048db.png#clientId=u307d0e74-2c27-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=817&id=ucba1ccc6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1226&originWidth=1627&originalType=binary&ratio=1&rotation=0&showTitle=false&size=188504&status=done&style=none&taskId=u7fcfcddd-f358-4312-a757-9f5d7149ffd&title=&width=1084.6666666666667)
3. 重写
- 子类重写父类的方法,与属性无关
- 父类的引用指向了子类(父类 对象 = new 子类();)
- 只能重写非静态方法(@Override)
- 方法名和参数列表必须相同
- 修饰符:范围可以扩大,但是没可以缩小 public > protected > Default > private
- 抛出的异常:范围可以被缩小,但是不能扩大 classNotFoundException --> Exception(大)
> 为什么需要重写:
> 1. 父类的功能,子类并不一定需要,或不能满足子类的需求
<a name="XtPhS"></a>
### 多态
- 即同一个方法可以根据发送对象的不同而采用多种不同的行为方式
- 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多
- 多态存在的条件
- 有继承关系
- 子类重写父类的方法
- 父类引用指向子类对象
- 多态是方法的多态,属性没有多态
- 强制类型转换:可以由父类强制转化为子类(高转低)
> 1. static 方法: 属于类,它不属于实例
> 2. final 常量
> 3. private方法
```java
// 一个对象的实际类型是确定的
// new Person();
// 可以指向的引用类型就不确定了: 父类的引用指向子类
Sudent s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
// 对象能执行那些方法主要看左边的类型
// 左边有的可以用,没有不可以用;如果子类没有重写父类的方法,执行父类的方法
// 父类不能调用子类单独存在的方法
- instanceof(类型转换) 引用类型,判断一个对象是什么类型 ```java Object obj = new Student(); // Student 是Person的子类,Teacher也是Perosn的子类
System.out.println(obj instanceof Student); // true System.out.println(obj instanceof Person); // true System.out.println(obj instanceof Object); // true System.out.println(obj instanceof Teacher); // false System.out.println(obj instanceof String);// false
// 同级引用之间无法使用instanceof Student stu = new Student(); System.out.print(stu instanceof Teacher); // 编译不了
// 强制类型转换 Student stu1 = new Student();
((Person)stu1).test();
Person per = stu1;
per.text(); // 无法使用 子类转化为父类自动转化,但是可能会丢失自己本来的一些方法
![image.png](https://cdn.nlark.com/yuque/0/2022/png/13002623/1650727444970-34fcf73f-dcba-4854-936b-b92d365dbba7.png#clientId=uf9bd27ac-80a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=276&id=u21a202c2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=295&originWidth=790&originalType=binary&ratio=1&rotation=0&showTitle=false&size=34362&status=done&style=none&taskId=ua7ce053e-29d1-41b6-8ce1-8ad82683020&title=&width=738.6666870117188)
- 作用
- 方便方法的调用,减少重复的代码!简洁
<a name="I55xO"></a>
### 抽象类
- abstract修饰符可以用来修饰方法,也可以用来修饰类;如果用来修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
- 抽象类中没有抽象方法,但是抽象方法的类一定要声明为抽象类
- 抽象类,不能使用new 关键字来创建对象,它只能由子类来继承
- 抽象方法,只有方法的声明,没有方法的实现,它是用来给子类继承的
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
![image.png](https://cdn.nlark.com/yuque/0/2022/png/13002623/1650729484799-e625b6f3-7935-4f57-acbd-dea4bcc7f4c8.png#clientId=u5cae338d-5954-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=610&id=u5eb95fa2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=915&originWidth=1104&originalType=binary&ratio=1&rotation=0&showTitle=false&size=100734&status=done&style=none&taskId=ua4b0367f-584f-4565-af52-a8c9cf87eb5&title=&width=736)
<a name="bVDJ5"></a>
### 接口(interface)
- 普通类: 只有具体实现
- 抽象类: 具体实现和规范(抽象方法)都有
- 接口: 只有规范 (约束和实现分离:面向接口编程)
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是......你必须......”的思想。如果你是一个人,你必须有良心。如果是一台车,必须能跑,必须有发动机。
- 接口的本质是契约,就像我们人间的法律一样,制定好后大家一起遵守
- OO的精髓,是对对象的抽象,最能体现这一点的就是接口,为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++,java,c#等),就是因为设计模式所研究的,实际上就是合理的抽象
```java
package com.xy.app;
/*
第一个接口
*/
public interface Inter {
// 默认带有 public abstract
void add(String name);
void update(String name);
void del(String name);
void query(String name);
}
-----------------------
package com.xy.app;
/*
第二个接口
*/
public interface Service {
void get(String id);
}
-----------------------
package com.xy.app;
// 抽象类: extends
// 类 可以实现接口 implements 接口
// 实现了接口的类,就需要重写接口中的方法
// 利用接口,实现继承
public class Im implements Inter, Service{
@Override
public void get(String name){
}
@Override
public void add(String name) {
}
@Override
public void update(String name) {
}
@Override
public void del(String name) {
}
@Override
public void query(String name) {
}
}