1. OOP思想
概念: 面向对象编程(Object Oriented Programming,OOP)是种计算机编程架构,在考虑问题时以具体的事物对象为单位,考虑它的属性和方法,它可以使人们的编程与实际的世界更加接近,所有的对象被赋予属性和方法,这样变成就更加富有人性化、模拟现实世界中的概念、是一种设计和实现软件系统的思想。
- 面向过程思想:
- 面向过程的设计思想在考虑问题时,是以一个具体的流程为单位,考虑它的实现办法,关心的是功能的实现,比如我们完成一个需求的步骤,要做什么,怎么做,第一步,第二步...得到结果。每一个步骤,每一个过程,我们都参与其中,然后得到最终我们想要的结果。
- C语言就是典型的面向过程的语言
- 面向对象思想:
- 面向对象和面向过程是相辅相成的,而不是互斥的,比如说有个需求是将大象装进冰箱:第一步打开冰箱门,第二步把大象装进去,第三步把冰箱门带上...这种简单的、不需要协作的问题,使用面向过程的思想显然是最好的。
- 但如果需求是制作一个冰箱这种复杂的事务,面向过程就很困难了,需要面向对象的思维来设计冰箱的结构图、颜色、大小、噪音...等等一系列的属性和行为。
- 当然,宏观上使用面向对象设计,微观上仍然要使用面向过程来实现。
- OOP四大特征:
- OOP的四大特征是:抽象、封装、继承、多态。
- OOP的三大特征是:封装、继承、多态。(因为抽象不涉及代码)
2. 对象
概念: 当我们认识到一种新的物体,它叫树,于是在我们的意识当中就形成了树的概念,这个概念会一直存在于我们的思维当中,并不会因为这棵树被砍掉而消失,这个概念就是现实世界当中的物体在我们意识当中的映象,就是一个对象。
- 对象特征: 而对于java程序而言,对象具有如下三个特征:
- 万事万物皆对象,如一个苹果,一项政策,一种心情等。
- 对象具有唯一性,就像世界上不可能出现两片相同的叶子。
- 对象可以具有属性和行为(方法)。
3. 抽象
概念:
- 所谓抽象即抽出相象的部分,也叫提取,提炼或者归纳总结,就是忽略一个主题中与当前目标无关的那些方面,以便充分地注意与当前目标有关的方面,然后将这些我们关注的部分,归纳总结在一起,形成一个概念类。
- 抽象作用: 主要是用来把客观世界中真实存在的事物用编程语言描述出来。
图示: 下图中,哪些是狗,哪些是狼?
总结:
- 首先,这些动物的身高、体重、血型、出生日期等等属性,我们会自动的忽略掉,因为我们不关心(忽略无关)。
- 然后,眼神凶恶、尾巴向下、群居动物、责任心重、团结、会捕猎、会嗷嗷叫... 这些属性和方法被我们抽取出来,归纳总结成狼类,这个狼类会成为你心里的一个"标准",或者叫"模板",如果让你创建一只真实的狼出来,你一定会按照这个"模板",将这些属性和方法赋予你创造出来的"狼"。
- 最后,眼神二逼、尾巴向上、独居动物、无责任心、忠诚、会卖萌、会汪汪叫... 这些属性和方法被我们抽取出来,归纳总结成犬类,这个犬类会成为你心里的一个"标准",或者叫"模板",如果让你创建一只真实的狗出来,你一定会按照这个"模板",将这些属性和方法赋予你创造出来的"狗"。
- "狼类模板"和"犬类模板"是我们通过抽象思想获得出来的,而"一只真实的狼"和"一只真实的狗",是你通过对应的"模板"创造(new)出来的。
- 类与实例的关系: JAVA中,类就是"模板",实例就是"狼"或者"狗",我们通过对一个一个的实例抽象归纳,从而得到模板,我们通过模板实例化,得到对应的实例。
4. 封装
概念:
- 封装(Encapsulation)是一个过程,先"装"后"封",就是将属性和方法一起包装到一个程序单元中,并隐藏方法的实现过程,封装过程的结果,以类的形式实现。
- 类就是对象通过抽象的思想将比较关注的属性和方法提取出来,然后再将这些属性和方法封装到一个单元中而形成的最终产物。
4.1 装
概念:
- 对于上面的案例,我们已经通过抽象得到了一个"狼类"和"狗类",也得到了一堆它们对应的属性和方法,但这些东西不能只存在于我们的想象和记忆中,我们需要把它们纪录下来,对于java来说,就是纪录在一个类中。
- 通过抽象思想得到想要关注的属性和方法,然后把它们写在一个类中,这个过程就是"装"。
伪代码: 狼类.java
狼类{
属性:
眼神 = 凶恶;
尾巴 = 向下;
生活习性 = 群居;
性格 = [责任心重,团结]
方法:
捕猎方法();
嗷嗷叫方法();
}
复制代码
伪代码: 犬类.java
犬类{
属性:
眼神 = 二逼;
尾巴 = 向上;
生活习性 = 独居;
性格 = [无责任心,忠诚]
方法:
卖萌方法();
汪汪叫方法();
}
复制代码
4.2 封
概念:
- 封装意义: "封"是为了保护对象隐私,保护对象内部实现细节,隔离变化。
- 隔离变化: 对象内部是非常容易变化的,就像机箱内部的硬件或者配置,实时更新,但是封装到一个机箱后,你不需要实时跟进,无论里面怎么变化,给你的功能都是不会变的,开机重启,usb接口等等。但是这种隔离,面对不同的调用者,是可以有不同的权限的,这被称之为封装的权限。
- 封装权限: 比如现实生活中去转户口,需要透露自己大量甚至全部的信息,父母亲面前,需要透露稍微少一些的信息,朋友面前就会透露的更少了,关于一些自己的小秘密,只有自己知道…
- Java的属性和方法也有相对应的权限,通过很明显的标记来标识,叫权限修饰符。
同类 | 同包 | 不同包父子类 | 不同包无关类 | |
---|---|---|---|---|
public | 可访问 | 可访问 | 可访问 | 可访问 |
protected | 可访问 | 可访问 | 可访问 | |
默认(友元) | 可访问 | 可访问 | ||
private | 可访问 |
5. 类的分类
概念: 之前的学习中,我们一直在使用JDK提供给我们的类,如String、Scanner等,接下来我们要创建一个属于自己的类。
- 类以
class
为关键字,在一个java文件中可以有多个并列的class
,但是public
修饰的class
只能有一个。 - 类根据不同的修饰和位置,可以分为五种:
public class A{}
:公共类:所有类都可以访问。class A{}
:友元类:同包可以访问的。final class A{}
: 最终类:不能被继承,且final类中的所有属性也都是final的。static class A{}
:静态类:只能写在其他类内部。abstract class A{}
:抽象类:可以包含抽象方法的类。
- 类的名字: 类名其实是类的简称,建议首字母大写驼峰制度,类的全名是包名加上类名的组合。
源码:
public class MyClass{
// 类体:类中存放属性和方法
}
class MyClass01{}
class MyClass02{}
复制代码
6. 类的实例化
概念:
- 实例: 在软件系统运行时,通过类来创建实例
instance
,这一过程叫做实例化,创建出来的对象被称为该类的实例。 - 声明赋值过程: 实例化的过程就是通过new关键字来在堆内存中开辟一块空间a,然后再调用该类的构造器将该类构造出来并放到空间a里面的过程。
- 在我们设计模板的时候必须设计一个构造器。
- 如果没有设计构造器则默认使用模板自带的一个构造器。
- 在实例化的过程中,必须调用构造器才可以。
- 成员属性的调用: Java中的调用使用分量符"."
- 非静态的成员属性属于某个实例,是互相独立的,使用所属的实例名调用。
- 静态的成员属性属于类(也成为类属性),是共享且唯一的,使用类名直接调用。
源码: Person.java
/**
* @author JoeZhou
*/
public class Person {
public int id = 1;
String name = "张三";
public static int age = 23;
private String gender = "女";
}
复制代码
源码:
@Test
public void instance(){
// 变量类型 变量名 = new 构造器();
Person zhaosi = new Person();
System.out.println(zhaosi);
}
@Test
public void changeForNoStaticField(){
Person zhaosi = new Person();
Person liuneng = new Person();
zhaosi.id = 50;
System.out.println(liuneng.id);
}
@Test
public void changeForStaticField(){
Person zhaosi = new Person();
Person liuneng = new Person();
// 静态属性不属于某个实例,而是属于这个模板
Person.age = 50;
System.out.println(Person.age);
}
复制代码
练习: 02001-6
- What is required at line 5 in class SomeApp to use the process method of BitUtils?
package util;
public class BitUtils {
private static void process(byte[] b) {}
}
// 5
package app;
public class SomeApp {
public static void main(String[] args) {
byte[] bytes = new byte[256];
// insert code here
}
}
复制代码
- A. process(bytes);
- B. BitUtils.process(bytes);
- C. app.BitUtils.process(bytes);
- D. util.BitUtils.process(bytes);
- E. import util.BitUtils.*; process(bytes);
- F. SomeApp cannot use the process method in BitUtils.