OOP(Object Oriented Programming) 面向对象程序设计(核心:设计)
面向对象思想阶段: 第一阶段:面向对象基本思想(JavaSE) 第二阶段:面向接口编程思想(jdbc,web,框架) 第三阶段:面向切面编程思想(Spring框架) 面向过程和面向对象 面向过程:代表是C语言,强调的是过程,偏重事情"怎么做",将自己比喻成"执行者",基本单位:函数 面向对象:代表是Java语言,强调的是对象,偏重事情"找谁做",将字节比喻成"指挥者",基本单位:类 面向过程往往解决的是一些较小的问题 面向对象往往解决的是一些较大的问题 两种思想没有好坏之分,都是人们在生活中解决问题的手段而已
面向对象三大特征:
封装,继承,多态
类:一类事物的统称
举例:人类,猫类,......
对象:一类事物的具体体现:
举例:那个长得像"周冬雨"的小姐姐,那个叫Tom的猫
关系:
类是抽象的,类是对象的抽象或模版
对象是具体的,对象是类的实例或实体
结论:
需要在以前代码(测试类)的基础上,完成对象所对应模版类的设计
学习面向对象的小技巧
1.找有没有合适帮助我们做事情对应的类
如果有,直接第2步;
如果没有,自己设计类
2.通过类创建对象
3.通过对象调用方法完成实际需求
类(class)
含义:
Java语言的基本单位
分类:
1.Java系统中提供的类(Java API中提供的类)
例如:String
2.程序员设计的类
包含:
类的成员
成员量
成员方法
成员内部类
类的内容
构造器
代码块
成员量
含义:
声明在类中方法外的变量或常量
分类:
成员变量:声明在类中方法外的变量
实例变量(对象变量):
声明在类中方法外,且没有static关键字修饰的变量,变量归属于对象
静态变量(类变量):暂不涉及
声明在类中方法外,且含有static关键字修饰的变量,变量归属于类
成员常量:声明在类中方法外的常量(暂不涉及)
实例常量(对象常量):
声明在类中方法外,且没有static关键字修饰的常量,常量归属于对象
静态常量(类常量):暂不涉及
声明在类中方法外,且含有static关键字修饰的常量,常量归属于类
成员方法
含义:
声名在类中的方法
分类:
实例方法(对象方法)
声明在类中且没有static关键字修饰的方法
静态方法(类方法)
声明在类中且含有static关键字修饰的方法
类的设计步骤
1.根据实际需求,在类中加入实例变量和实例方法完成基础模版类的设计 2.根据实际需求,在类中加入封装思想,提高模版类的数据的安全性 3.根据实际需求,在类中加入this关键字第一种用法,便于达到优化的效果 4.根据实际需求,在类中加入合适的构造器,便于对象创建的多元性 5.根据实际需求,在类中加入构造器代码块,便于达到优化的效果 6.根据实际需求,在类中加入this关键字第二种用法,便于达到优化的效果 7.根据实际需求,在类中加入静态概念 8.根据实际需求,在类中加入继承思想,便于提高代码的复用性 9.根据实际需求,在类中加入抽象概念,便于解决继承思想中的安全隐患 10.根据实际需求,在类中加入final关键字 11.根据实际需求,在类中加入接口概念 12.根据实际需求,在类中加入内部类概念 13.根据实际需求,在类中加入枚举类概念类的格式:
位置:
现阶段在和含有main()的类同包下创建另外一个类
格式:
public class 类名 {
实例变量
实例方法
}
对象的创建
位置:
在测试类中(含有main()的类中)
格式:
类名 对象名 = new 类名(实参);
对象的访问
获取格式:
对象名.实例变量名;
对象名.实例方法名(实参);
赋值格式:
对象名.实例变量名 = 初始化值;
//完成学生对象的创建
Student s1 = new Student();
System.out.println(s1);
//获取学生的姓名和年龄
System.out.println(s1.name);
System.out.println(s1.age);
//给学生对象进行赋值操作
s1.name = "卢小琪";
s1.age = 18;
//获取学生的姓名和年龄
System.out.println(s1.name);
System.out.println(s1.age);
//调用学生对象的方法
s1.study();
System.out.println("===================================");
//创建学生对象
Student s2 = new Student();
//获取学生的姓名和年龄
System.out.println(s2.name);
System.out.println(s2.age);
Student类
//实例变量
String name;
int age;
//实例方法
public void study () {
System.out.println(age + "岁的" + name + "正在学习HelloWorld!!!");
}
实例变量和局部变量区别
实例变量:声明在类中方法外,且没有static关键字修饰的变量
局部变量:声明方法内部或者方法声明上的变量
实例变量和局部变量的区别:
代码中声明位置不同:
实例变量:类中方法外
局部变量:方法内部或者方法声明上
内存中位置不同:
实例变量:堆内存
局部变量:栈内存
变量的默认值不同:
实例变量:含有默认值
局部变量:没有默认值
代码中的作用域不同:
实例变量:类中(静态成员除外)
局部变量:方法中
内存中的生命周期不同:
实例变量:随着对象的创建而加载,随着对象的回收而消失
局部变量:随着方法的调用而加载,随着方法的出栈而消失
加载方式不同:
实例变量:随着对象的创建而加载,每创建一次对象就会加载一次
局部变量:随着方法的调用而加载,每调用一次方法就会加载一次
this 关键字
变量的特点之一:
在同一作用域内不可以创建同名的变量
考虑到实例变量和局部变量不在同一作用域内,在同一个类中可以创建同名的实例变量和局部变量
this关键字的第一种用法:
应用场景:
(子)类中的实例方法
(子)类中的构造器
语法格式:
this.实例变量名;
this.实例方法名(实参);
语法作用:
用来区分同一个类中出现同名的实例变量和局部变量
语法含义:
哪个对象调用了this关键字所在的实例方法或构造器,this关键字就代表哪个对象
//创建Var对象
Var var = new Var();
var.method();
System.out.println("========================");
//创建Var对象
Var var1 = new Var();
System.out.println("var1 = " + var1);
var1.show();
System.out.println("=============");
//创建Var对象
Var var2 = new Var();
System.out.println("var2 = " + var2);
var2.show();
Var 类
//实例变量
int num = 10;
public void method () {
//局部变量
int num = 20;
System.out.println("num = " + num);//20 就近原则
System.out.println("this.num = " + this.num);
}
public void show () {
System.out.println("this = " + this);
}
封装
含义:
给程序中不同的内容添加不同的权限访问级别,使之提高数据的安全性
好处:
提高程序的安全性
核心:
四种权限访问级别
四种权限访问级别(三种权限修饰符)
分类(从大到小关系):
public > protected > 缺省(省读音"sheng",什么都不写) > private
private关键字
含义:
私有的
修饰:
成员量,成员方法,成员内部类,构造器
作用:
被private修饰的内容只能在本类中进行访问
私有变量:
含义:
被private修饰的成员变量
作用:
被private修饰的成员变量只能在本类中进行访问
格式:
private 修饰符 数据类型 变量名;
使用封装思想(private)优化模版类:
1.需要将模版类中所有的成员量进行私有化
2.针对模版类中每个被私有化的成员量提供一对的公共访问方式(存储数据和获取数据的方法)
存储数据方法的两个明确:
返回类型:void
形参列表:存储数据的数据类型 变量名
获取数据方法的两个明确:
返回类型:获取数据的数据类型
形参列表:()中什么都不写
Student s = new Student();
//给学生对象进行赋值
s.setName("卢小琪");
s.setAge(18);
//System.out.println(s.name + "=" + s.age);
System.out.println(s.getName() + "=" + s.getAge());
Student 类
private String name;
private int age;
//存储姓名方法
public void setName (String n) {
name = n;
}
//获取姓名方法
public String getName () {
return name;
}
//存储年龄方法
public void setAge (int a) {
age = a;
}
//获取年龄方法
public int getAge () {
return age;
}
使用this关键字优化学生类
//创建学生对象
Student s = new Student();
//给学生对象进行赋值操作
s.setName("卢小琪");
s.setAge(18);
//调用学生对象的方法
s.study();
Student 类
//私有化所有成员量
private String name;
private int age;
//存储姓名
public void setName (String name) {
this.name = name;
}
//获取姓名
public String getName () {
return name;
}
//存储年龄
public void setAge (int age) {
this.age = age;
}
//获取年龄
public int getAge () {
return age;
}
public void study () {
System.out.println(age + "岁的" + name + "正在学习HelloWorld!!!!");
}
构造器(构造方法)
作用:
1.关键字new根据构造器创建对象
2.给类中的实例成员进行初始化操作
3.如果是有参的构造器,类似于set()的功能给实例变量进行赋值操作
格式:
修饰符 类名 () {
第一部分:
隐式或显式的super(实参)
第二部分:
隐式的实例初始化过程
第三部分:
构造器中除了super()显式的代码
}
注意事项:
1.当一个类没有任何构造器的时候,JVM自动给其分配一个public的无参构造器,用于对象成员初始化操作;
当一个类一旦有任何的构造器时,JVM不在为其提供;
2.构造器的名字必须与类名相同
3.构造器的语法格式和方法比较相似,所以构造器也被称之为构造方法,需要注意构造器没有返回类型,而且
连void关键字都不能有
4.构造器中代码存在三个部分,无论任何时候,前面部分总是优先于后面部分执行(暂不涉及隐式部分代码,
只涉及构造器中显式的代码)
5.构造器支持方法的重载
//类名 对象名 = new 类名(实参);
Student s = new Student(1);
public Student () {
System.out.println("无参构造器");
}
public Student (int a) {
System.out.println("有参构造器");
}
JavaBean(标准类)
场景:
根据架构师设计的数据库"表结构"编写模版类
含义:
当架构师或上级没有任何特殊要求时,程序员间一种设计类约定俗成的规范
内容:
1.一个.java文件中只能编写一个类文件(class,interface,enum)
2.该.java文件中类文件的权限访问级别必须是public
3.必须有:
(1)类中的所有成员量必须给其进行私有化
(2)针对每个被private修饰的成员量提供一对的公共访问方式
(3)无参构造器
4.可以有:
(1)有参构造器
(2)三个特殊的实例方法
toString()
equals()
hashCode()
(3)成员内部类
(4)构造器代码块
(5)静态代码块
自动生成代码快捷键: Alt + Insert
//使用无参构造器创建学生对象
Student s1 = new Student();
//给学生对象进行赋值操作
s1.setName("卢家琪");
s1.setAge(18);
//调用学生的学习方法
s1.study();
System.out.println("======================");
//使用有参构造器创建学生对象
Student s2 = new Student("卢佳琪", 18);
//调用学生的学习方法
s2.study();
//标准类
//私有化实例变量
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void study () {
System.out.println(age + "岁的" + name + "正在学习HelloWorld!!!");
}
匿名对象
含义:
没有名字的对象
好处:
提高内存的使用率
弊端:
只能使用唯一的一次
应用场景:
有些情况当对象只使用唯一的一次时,可以使用匿名对象,提高内存的使用率
//创建对象
Student s = new Student();
//调用method();
method(s);
method(new Student());
public static void method (Student s) {
System.out.println(s);
}
对象数组
含义:数组中的元素是引用类型的对象
//创建3个学生对象
Student s1 = new Student("唐小妃", 18);
Student s2 = new Student("城小将", 18);
Student s3 = new Student("李小白", 18);
//创建学生对象数组
Student[] arr = {s1,s2,s3};
//遍历数组
for (int i = 0; i < arr.length; i++) {
Student s = arr[i];
if (s != null) {
s.study();
}
}
//Student 类
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void study () {
System.out.println(age + "岁的" + name + "正在学习HelloWorld!!!");
}
//结果
18的唐小菲正在学习HelloWorld
19的城小将正在学习HelloWorld
20的李小白正在学习HelloWorld
类中的私有方法
应用场景:
当类中多个方法存在共性内容,可以将这些共性内容进行向上抽取成另外一个方法,
但这个方法时供我们自己使用,不想让外界所访问,
这个时候我们可以将这个方法修饰为private
特点:
被private修饰方法只能在本类中访问,在本类之外无法进行访问
格式:
private 修饰符 返回类型 方法名 () {}
//创建PrivateMethod对象
PrivateMethod pm = new PrivateMethod();
//调用方法
pm.method01();
System.out.println("===========");
pm.method02();
System.out.println("===========");
//PrivateMethod 类
public void method01 () {
method();
System.out.println("他好");
}
public void method02 () {
method();
System.out.println("我也好");
}
private void method () {
System.out.println("你好");
System.out.println("我好");
System.out.println("大家好");
}
//结果
你好
我好
大家好
他好
============
你好
我好
大家好
我也好
============
构造器代码块
应用:
当所有的构造器中存在相同代码时,可以将这些相同代码存储到构造器代码块
格式:
{
所有构造器中相同的代码
}
位置:
类中,方法外
注意:
构造器代码块无需自己调用,由构造器中的第二部分隐式代码进行调用
//创建学生对象
new Student();
System.out.println("===========");
new Student(1);
//Student 类
public Student () {
//第一部分隐式或显式代码
//第二部分隐式代码
//第三部分显式代码(super()除外)
System.out.println("他好");
}
public Student (int num) {
System.out.println("我也好");
}
{
System.out.println("你好");
System.out.println("我好");
System.out.println("大家好");
}
//结果
你好
我好
大家好
他好
============
你好
我好
大家好
我也好
this关键字的第二种用法
应用场景:
(子)类的构造器中
格式:
this(实参);
作用:
调用本类中其它的构造器完成初始化工作
含义:
当类中部分构造器出现相同代码时,将相同代码的工作交给一个构造器进行完成,其它部分构造器调用该构造器即可
public Student() {
this(1);
System.out.println("无参构造器");
}
public Student (int a) {
this(1,2);
System.out.println("有一个参数的构造器");
}
public Student(int a , int b) {
//隐式部分代码
System.out.println("有两个参数的构造器");
}
{
System.out.println("构造器代码块");
}
static关键字
含义:
静态的,共享的
修饰:
成员量,成员方法,代码块,成员内部类
特点:
1.被static修饰的内容不再属于对象,而是归属类,会被这个类创建的所有对象所共享
2.被static修饰的内容随着类(类文件,也就是字节码对象)的加载而加载,而且只加载唯一的一次
静态变量
含义:
被static关键字修饰的成员变量
格式:
修饰符 static 数据类型 变量名;
特点:
被static修饰的成员变量不在归属于对象,而是归属于类,会被通过这个类创建的所有对象所共享
调用:
类名.静态变量名;
对象名.静态变量名;(虽然不会报错,不推荐使用)
Student.classroom = "射雕";
Student s1 = new Student("郭靖",18);
Student s2 = new Student("黄蓉",16);
Student s3 = new Student("洪七公",50);
Student.classroom = "神雕";
//s2.setClassroom("神雕");
//s3.setClassroom("神雕");
System.out.println(s1.print());
System.out.println(s2.print());
System.out.println(s3.print());
public String print () {
return name + "=" + age + "=" + classroom;
}
三种变量的区别:
代码中位置不同:
局部变量:代码块内部或者方法声明上
实例变量:类中代码块外
静态变量:类中代码块外
内存中位置不同:
局部变量:栈内存
实例变量:堆内存
静态变量:堆内存
默认值不同:
局部变量:没有默认值
实例变量:含有默认值
静态变量:含有默认值
代码中作用域不同:
局部变量:所属代码块中
实例变量:所属类中(在静态成员中无法使用)
静态变量:所属类中
内存中生命周期不同:
局部变量:随着方法的调用而加载,随着方法的出栈而消失
实例变量:随着对象的创建而加载,随着对象的回收而消失
静态变量:随着类的加载而加载,随着类的回收而消失
加载次数和方式不同:
局部变量:随着方法的调用而加载,每调用一次方法,方法中的局部变量就会加载一次
实例变量:随着对象的创建而加载,每创建一次对象,堆内存中的实例变量就会加载一次
静态变量:随着类的加载而加载,因为类的加载只有唯一的一次,所以静态变量也只会加载唯一的一次
自动分配学号
//创建学生对象
Student s1 = new Student("唐小妃", 18);
Student s2 = new Student("城小将", 18);
Student s3 = new Student("李小白", 18);
Student s4 = new Student();
s4.setName("波斯王");
s4.setAge(18);
System.out.println(s1.print());
System.out.println(s2.print());
System.out.println(s3.print());
System.out.println(s4.print());
//Student 类
private int id;
private String name;
private int age;
private static int num = 220411001;
{
this.id = num++;
}
public Student() {
//this.id = num++;
}
public Student(String name, int age) {
//this.id = num++;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String print () {
return id + "=" + name + "=" + age;
}
//结果
220411001 = 唐小妃 = 18
220411002 = 城小将 = 18
220411003 = 李小白 = 18
220411004 = 波斯王 = 18
静态方法
含义:
被static修饰的成员方法
特点:
1.被static修饰的成员方法不再属于对象,而是归属于类,会被这个类创建的所有对象所共享
2.有些时候创建对象的目的不是为了多次使用对象,而是多次使用对象中的实例方法,这个时候对象只会创建唯一的一次,该对象本身
会一直驻留堆内存,比较浪费内存资源,这个时候可以将这些工具方法都声明为static,通过类名进行调用,无需再进行对象的创建,为
了方式对象强制进行创建,习惯性将这个类的构造器进行私有化
格式:
修饰符 static 返回类型 方法名 () {}
调用:
类名.静态方法名(实参);
对象名.静态方法名(实参);(**不推荐这种调用方式**)
静态方法的加载指的是进入静态区
静态方法的调用指的是进入栈内存
静态方法的注意事项:
1.静态方法随着类的加载而加载,而且只加载唯一的一次(注意:不是只能调用一次)
2.静态方法虽然不属于对象,而是属于类,但是会被这个类创建的所有对象所共享,使用对象名也可以调用静态方法,不推荐这种调用方式
3.静态方法中调用成员关系:在静态方法中不可以调用非静态成员
实例方法中调用非静态成员:结论成立
实例方法中调用静态成员:结论成立
静态方法中调用静态成员:结论成立
静态方法中调用非静态成员:结论不成立
4.静态方法中不可以使用this关键字
静态代码块
含义:
被static修饰的代码块
位置:
类中,方法外
学习目的:
1.提高对象的加载时机,封装高级工具类(暂不涉及)
2.类的初始化过程面试题(暂不涉及)
3.给静态常量进行初始化赋值(暂不涉及)
格式:
static {
}
注意:
1.静态代码块会随着类的加载而加载,而且只加载唯一的一次
2.静态代码块中无法使用非静态成员
3.静态代码块中无法使用this关键字



