(一)、面向对象
(1)、概述
面向对象(Object Oriented)是软件开发方法,一种编程范式。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。
面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。
(2)、面向过程和面向对象
①、面向过程
侧重分步骤,类似于公司的扁平化管理
比如 五子棋
面向过程的设计思想就是首先分析问题 :
1 开始游戏
2 黑子先走
3 绘制画面
4 判断输赢
5 白子走
6 绘制画面
7 判断输赢
8 .....
②、面向对象
侧重分模块,类似于公司的层级管理
比如五子棋
面向对象的设计思想来解决问题 :
五子棋可以分为
1 黑白双方,行为一模一样,形成棋子系统
2 棋盘系统,负责绘制画面
3 规则系统,比如判断输赢,是否违规等操作
面向对象是以功能划分,而不是步骤,
类似于炒饭和盖饭,盖饭就等于 是面向对象,饭菜分离,可以任意组合,耦合度降低
优点 : 维护简单,可扩展性,可重用性
(3)、类和对象
对象 :
代码角度 : new 的实例化某一个类的实例,封装特有的数据
数据角度 : 封装数据和逻辑的一种方式
人类认知角度 :对象就是具体的个体,一切皆对象
设计角度 : 从一个实际的实体抽象某些属性的一种实体表示
概念/定义 :
是我们在思想上对某一个东西,或者某一类东西的唯一性标识 描述了这一类事物的特性 是我们对客官事物描述的一个标准,一个模板
类定义标准和模板 , 而对象就是符合这个标准的个体
我们再抽离某个概念,就能建立相关事物的类,一定通过类中的属性来形成这个概念, 然后通过这些属性就形成类,通过不同的属性值形成了不同的个体(对象)
通过不同的属性,划分不同的类,通过不同的属性值,划分不同的个体
从类到对象的过程,可以理解为对成员变量赋值的过程
堆内存每个对象空间分为3块
1 数据区域 : 成员变量
2 头部 : hash值
3 类型 : 静态区类文件的空间引用
什么时候使用静态变量,什么时候使用成员变量
静态变量是类级别的,对象无关,静态变量的属性和值 是所有对象都一致的
成员变量是对象级别的,它们拥有相同的属性,但值可以相同也可以不
(4)、对象使用和特征
①、JVM特性
跨平台,多线程,自动垃圾回收,面向对象
垃圾 : 没有更多引用指向这个对象(谁也找不到),该对象被视为垃圾数据,等待被回收
②、面向对象特性
继承性,封装性,多态性,抽象
③、对象使用
public class Student {
String name;
int age;
String addr;
String sex;
}
public class OOP_01 {
public static void main(String[] args) {
// 创建student类对象
Student s1 = new Student();
System.out.println(s1);
// 成员变量赋值
s1.name = "张三";
// 获取
System.out.println(s1.name);
// 成员变量和静态变量都有默认值
System.out.println(s1.addr);
// 同类的多个对象,属性一定是一致的,只是值可以相同可以不同
Student s2 = new Student();
s2.name = "李四";
System.out.println(s2.name);
}
}
④、常见异常
空指针是运行时异常,编译时不报错,一般因为程序员粗心导致
public class OOP_02 {
public static void main(String[] args) {
// 创建对象
Star star = new Star();
// 调用成员变量
System.out.println(star.age);
// 没有name变量,所以不可以调用
// System.out.println(star.name);
star.test();
// 所有引用数据类型都可以赋值为null
star = null;
// 使用null 访问成员属性,会报错,空指针异常
System.out.println(star.age);
}
}
class Star {
int age;
public void test() {
System.out.println("test方法");
}
}
空指针,只要是空指针,说明使用null调用了成员属性
(5)、JavaBean
1 公共类
2 私有属性
3 getter/setter方法
4 构造方法
public class Student {
String name;
private int age;
String addr;
String sex;
// ....
public void setAge(int age1) {
if (age1 <= 0) {
age = 1;
} else {
age = age1;
}
}
public class OOP_01 {
public static void main(String[] args) {
// 创建student类对象
Student s1 = new Student();
System.out.println(s1);
// 成员变量赋值
s1.name = "张三";
// 获取
System.out.println(s1.name);
// 成员变量和静态变量都有默认值
System.out.println(s1.addr);
System.out.println(s1.getAge());
s1.setAge(22);
// 同类的多个对象,属性一定是一致的,只是值可以相同可以不同
Student s2 = new Student();
s2.name = "李四";
System.out.println(s2.name);
}
}
(6)、传引用
传值和传引用
传值 : 传递基本数据类型 传引用 : 传递引用数据类型
public class OOP_03 {
public static void main(String[] args) {
int i = 10;
m1(i);
System.out.println(i);
System.out.println("------------");
Animal a = new Animal();
a.age = 10;
m2(a);
System.out.println(a.age);
}
public static void m1(int i) {
i++;
System.out.println(i);
}
public static void m2(Animal a) {
a = new Animal();
a.age++;
System.out.println(a.age);
}
}
class Animal {
int age;
}
(7)、构造方法
/**
* 编译器功能 : 1 把java文件编译成class文件 2 检查语法结构是否合法 3 帮我们把不规范的代码,补齐 比如
* 静态变量,需要类名调用,但是一般我们调用当前类中的静态变量的时候,不会加类名 此时 编译器
* 就会自动帮我们加上(如果我们不加类名访问,编译器自动帮我们加上当前类的类名)
* 另外就是构造方法,如果类中没有显示声明构造方法的话,则编译器会自动帮我们创建一个公共的无参构造
*
* 构造方法 : 创建当前类的实例化对象,并初始化成员属性
*
* 语法 : [权限修饰] 类名(参数列表){ 方法体 } public,private这些
*
* 如果我们不定义构造方法,则默认有一个公共的无参构造( public 类名(){} )
*
* 一旦我们指定了构造方法,则默认的无参构造就没有了 所以 一般我们需要指定构造方法的时候,要考虑再写一个无参构造
*
* 构造方法重载 : 可以根据需求,编写多个构造方法,方法名相同,参数列表不同(个数,类型)
*
*/
public class Constructor_01 {
public static void main(String[] args) {
Constructor_01 constructor_01 = new Constructor_01();
Student s = new Student("xxxx");
System.out.println(s.name);
Student s1 = new Student("xxxx", 5);
System.out.println(s1.name);
System.out.println(s1.age);
}
public static void addUser(User user) {
}
}
class User {
String username;
String password;
String nickname;
String sex;
int age;
String addr;
}
class Student {
String name;
int age;
// 需求 : 学生必须有name属性的值,age可以有,可以没有
public Student(String name1) {
name = name1;
System.out.println(111113);
}
public Student(String name1, int age1) {
name = name1;
age = age1;
System.out.println(111113);
}
}
(8)、构造方法和成员方法
public class Constructor_02 {
public void Constructor_02(int i) {
}
public Constructor_02() {
}
public static void main(String[] args) {
new Constructor_02();
// 构造方法可以和成员方法同名
// 就看返回值即可,因为构造方法没有返回值,连void都没有
// new Constructor_02(10);
}
}
(9)、This
①、This是什么
this关键字
this是每个对象中,保存自身内存地址的一个引用类型的成员变量
this 就表示这个对象,this的类型就是当前类的类型
当前类 :this所在的类,就是当前类
只能出现在成员方法和构造方法中,不能出现在静态方法中
谁调用的这个成员方法,this就是谁
②、能干什么
功能 :
1 用在成员方法/构造方法中,用来区分同名的成员变量和局部变量 this.xxx ;
2 用在构造方法中,重载调用当前类的其他构造方法this(参数); 必须写在构造方法第一行
3 return this ; 可以返回当前对象的内存地址,做到链式调用
③、怎么用
(①)、区*部变量和成员变量
public class This_01 {
class MyDate {
int year;
int month;
int day;
public void setDay(int day) {
this.day = day;
}
public MyDate() {
this.year = 1970;
this.month = 1;
this.day = 1;
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
}
如何区分同名的局部变量和静态变量 ? 类名.静态变量名
如何区分同名的局部变量和成员变量 ? this.成员变量名
(②)、重载调用其他构造方法
public class This_01 {
public static void main(String[] args) {
// System.out.println(this);
MyDate date = new MyDate(2008, 8, 8);
date.print();
// 需求 : 年月日可以不传递,如果不传递 默认是 1970.1.1
MyDate d2 = new MyDate();
d2.print();
String s = "2";
}
}
class MyDate {
int year;
int month;
int day;
public void setDay(int day) {
this.day = day;
}
public MyDate() {
// this.year = 1970;
// this.month = 1;
// this.day = 1;
// 重载调用下面的有参构造,必须在构造方法的第一行
this(1970, 1, 1);
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
// ....
}
public void print() {
System.out.println(year + "年" + month + "月" + day + "日");
}
}
(③)、链式调用
public class This_03 {
public static void main(String[] args) {
This_03 t = new This_03();
t.m1();
t.m2();
// 因为m1返回值是This_03类型,所以需要使用This_03来接收
This_03 t2 = t.m1();
t2.m2();
// 返回this 可以链式调用当前类中的成员方法
t.m1().m2();
// 返回其他类的对象,就可以链式调用其他类中的方法
t.m3().charAt(1);
t.m1().m4().m5().m2();
}
public String m3() {
return "zxcdsad";
}
public This_03 m1() {
System.out.println(1);
return this;
}
public This_03 m4() {
System.out.println(1);
return this;
}
public This_03 m5() {
System.out.println(1);
return this;
}
public void m2() {
System.out.println(2);
}
}