一、什么是面向对象
1、面向过程思想
在理解面向对象思想之前,我首先来回顾一下以前c语言中的面向过程思想,面向过程思想强调的是过程(动作),在面向过程的开发中,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然而由这些功能方法相互调用,完成需求。面向过程的典型代表语言是:C语言。2、面向对象思想
①面向对象思想的由来
随着需求的更改,功能的增多,发现需要面对每一个步骤太麻烦了,这时候就在思考,能不能把这些步骤和方法封装起来,根据不同的功能,进行不同的封装,用的时候,找到对应的类就可以了。这就是面向对象的思想。那么,到底什么是面向对象思想呢?
②面向对象思想概述
a、概念:面向对象是基于对象的编程思想。强调的是对象(实体),典型的语言是:C++,Java。
b、面向对象思想的特点:
- 是一种更符合我们思想习惯的思想
- 可以将复杂的事情简单化
- 是我们从执行者变成了指挥者,角色发生了转变。
- 首先,我们去寻找具备所需功能的对象来使用。
- 如果不存在这样的对象,那么我们就应该创建一个具备所需功能的对象。
- 这样可以提高代码的复用性,简化开发。
a、买电脑:
- 面向过程:我得先了解电脑——了解我自己的需求——找对应的参数信息——去电脑城买电脑——讨价还价——买回电脑。
- 面向对象:我知道我要买电脑——找一个了解电脑和会讨价还价的人去买——别人帮我买回来了。
- 面向过程:把衣服脱下——找一个盆——放点洗衣服——加点水——把衣服扔进去——搓一搓——请洗衣服——晾干——晒干
- 面向对象:我要洗衣服——把衣服脱下来——找到洗衣机——丢进去,开启洗衣机——洗完了,晒干。
public class Demo1{我们在面向对象的开发中,就是不断的创建对象,使用对象,指挥对象做事情。面向对象的设计过程,其实就是管理和维护对象之间的关系。
/*
把啤酒放进冰箱。
*/
public static void main(String[] args){
/*
面向过程:1、打开冰箱门。
2、把啤酒放进去。
3、关冰箱门
*/
//面向过程,调用方法:
open();
in();
close();
/*
面向对象:
如何思考才能更符合面向对象呢?
1、有那些类?
2、每个类有什么东西呢?
3、类与类之间有什么关系呢?
把啤酒放进冰箱的面向分析(名词提取法)
a、有几个类?大象,冰箱,Demo类
b、每个类有哪些东西呢?
————啤酒:进去
————冰箱:开,关
————Demo:main方法
*/
//面向对象,创建对象,对象调用方法
Beer beer = new Beer();
IceBox box = new IceBox();
box.open();
beer.in();
box.close();
}
public static void open(){
System.out.println("面向过程:打开冰箱");
}
public static void in(){
System.out.println("面向过程:把啤酒放进冰箱。");
}
public static void close(){
System.out.println("面向过程:关冰箱");
}
}
class Beer{
public static void in(){
System.out.println("面向对象:把啤酒放进去");
}
}
class IceBox{
public static void open(){
System.out.println("面向对象:打开冰箱");
}
public static void close(){
System.out.println("面向对象:关上冰箱");
}
}
⑤面向对象的思维方法
- 首先确定谁来做,其次确定怎么做。
- 首先考虑是整体,其次考虑是局部。
- 首先考虑是抽象,其次考虑是具体。
面向对象有三大特征,分别是:封装( encapsulation)、继承( inheritance)、多态( polymorphism)。
二、类与对象
1、什么是类?什么是对象?
①类和对象的概念
类是一组相关的属性和行为的集合。是构造对象的模板或蓝图。是一个抽象的概念。
对象是该类事物的具体表现形式。是一个具体存在的个体。
②类和对象的关系
对事物的描述通常包括两方面:一个是属性,一个是行为。只要明确该事物的属性和行为并定义在类中即可。对象其实就是该类事物实实在在存在的个体。
类和对象的关系可以理解成:类——对事物的描述。对象——该类事物的示例,在java中通过new创建来的。
类与对象的关系如图所示(图纸就是类,汽车就是对象):
③成员变量
定义类其实就是定义类的成员(成员变量和成员方法)
成员变量其实就是类中的属性。成员方法就是类中的行为。
成员变量和局部变量的区别:
- 成员变量定义在类中,整个类都可以访问;局部变量定义在函数中,语句局部代码快中,只在所属的区域有效。
- 成员变量存在于堆内存的对象中;局部变量存在于栈内存的方法中。
- 成员变量随着对象的创建而存在,随着对象的小时而消失;局部变量随着所属区域的执行而存在,随着所属区域的结束而释放。
- 成员变量都有默认的初始化值;局部变量没有默认的初始化值,必须先定义,赋值,才能使用。
④类与对象的代码示例:
/*⑤匿名对象(简述,在以后用到会详细说明)
事物:
属性事物的信息描述
行为事物的功能
类:
成员变量事物的属性
成员方法事物的行为
定义一个类,其实就是定义该类的成员变量和成员方法。
案例:我们来完成一个学生类的定义。
学生事物:
属性:姓名,年龄,地址...
行为:学习,吃饭,睡觉...
把事物要转换为对应的类:
学生类:
成员变量:姓名,年龄,地址...
成员方法:学习,吃饭,睡觉...
成员变量:和以前变量的定义是一样的格式,但是位置不同,在类中方法外。
成员方法:和以前的方法定义是一样的格式,但是今天把static先去掉。
首先我们应该定义一个类,然后完成类的成员。
*/
//这是我的学生类
class Student {
//定义变量
//姓名
String name;
//年龄
int age;
//地址
String address;
//定义方法
//学习的方法
public void study() {
System.out.println("学生爱学习");
}
//吃饭的方法
public void eat() {
System.out.println("学习饿了,要吃饭");
}
//睡觉的方法
public void sleep() {
System.out.println("学习累了,要睡觉");
}
}
a,概念:一个定义在另一个类内部的类。
b,当一个对象方法仅进行一次调用的时候,就可以简化成匿名对象。
c,匿名对象可以作为实际参数进行传递。
三、封装
1、封装的概念
封装是指隐藏对象的属性和细节,但对外提供公共的访问方式。
2、封装的好处
封装的好处主要在于:隐藏实现细节,提供公共的访问方式;将变化隔离;便于使用;提高代码的复用性;提高安全性。
3、封装的原则
封装原则主要是以下两点:
a、将不需要对外提供的内容都隐藏起来。
b、把属性都隐藏,提供公共方法对其调用。
4、private关键字
①private:私有,是一个权限修饰符,用于修饰成员。被private修饰的成员只有在本类中才能访问。私有仅仅是封装的一种体现而已。
②private常见的应用:将成员变量私有化,对外提供set和get方法对其进行访问,提高数据访问的安全性。
封装的代码示例如下:
/*
封装和private的应用:
A:把成员变量用private修饰
B:提高对应的getXxx()和setXxx()方法
*/
//定义学生类
class Student {
//姓名
private String name;
//年龄
private int age;
//姓名获取值
public String getName() {
return name;
}
//姓名设置值
public void setName(String n) {
name = n;
}
//年龄获取值
public int getAge() {
return age;
}
//年龄赋值
public void setAge(int a) {
age = a;
}
}
//测试类
class StudentTest {
public static void main(String[] args) {
//创建学生对象
Student s = new Student();
//使用成员变量
//错误:被私有修饰了,外界不能直接访问了
//System.out.println(s.name+"---"+s.age);
System.out.println(s.getName()+"---"+s.getAge());
//给成员变量赋值
//s.name = "林青霞";
//s.age = 27;
//通过方法给赋值
s.setName("黄祥");
s.setAge(20);
System.out.println(s.getName()+"---"+s.getAge());
}
}
四、构造函数
1、构造函数详解
①什么是构造函数:构造函数是一种特殊的方法。具有以下特点:
a,构造方法的方法名必须与类名相同。
b,构造方法没有返回值类型,也不能定义为void,在方法名面前不声明方法类型。
c,构造方法的主要作用是完成对象的初始化动作,它能把定义对象时的参数传递给对象的域。
d,一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无參的默认构造器,这个构造器不执行任何代码。
e,构造方法可以重载,以参数的个数,类型,顺序。
②构造函数的作用:给对象进行初始化。
③构造函数和一般函数的区别:
- 构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化;
- 构造函数,在对象创建时,会调用且只调用一次。
④什么时候定义构造函数:在描述事物时,该事物已存在就具备的一些内容,这些内容都定义在构造函数中。
⑤构造代码块
a,作用:给对象进行初始化,对象一建立就运行,而且优于构造函数运行。
b,和构造函数的区别:
- 构造代码块是给对象进行初始化,构造函数是给指定的对象进行初始化。构造代码块中定义的是不同对象的共性内容。
/*
构造方法代码演示
*/
class Student {
private String name;
private int age;
public Student() {
//System.out.println("我给了,你还给不");
System.out.println("这是无参构造方法");
}
//构造方法的重载格式
public Student(String name) {
System.out.println("这是带一个String类型的构造方法");
this.name = name;
}
public Student(int age) {
System.out.println("这是带一个int类型的构造方法");
this.age = age;
}
public Student(String name,int age) {
System.out.println("这是一个带多个参数的构造方法");
this.name = name;
this.age = age;
}
public void show() {
System.out.println(name+"---"+age);
}
}
class ConstructDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
s.show();
System.out.println("-------------");
//创建对象2
Student s2 = new Student("林青霞");
s2.show();
System.out.println("-------------");
//创建对象3
Student s3 = new Student(27);
s3.show();
System.out.println("-------------");
//创建对象4
Student s4 = new Student("林青霞",27);
s4.show();
}
}
2、类的初始化过程
Student s = new Student(); 在内存中究竟做了哪些事情呢?①加载student.class文件进内存。
②为栈内存s开辟空间。
③为堆内存学生对象开辟空间。
④对学生对象的成员变量进行默认初始化。
⑤对学生对象的成员变量进行显示初始化。
⑥通过构造方法对学生对象的成员变量进行赋值。
⑦学生对象初始化完毕,将对象地址赋值给s变量。
3、this关键字
①this关键字的含义:代表对象,this就是所在函数的所属对象的引用。简单的说,哪个对象调用了this所在的函数,this就代表哪个对象。
②this关键字的应用
a、当成员变量和局部变量重名,可以用关键字this来区分。
b、this也可以用于在构造函数中调用其它构造函数。
注意:this只能定义在构造函数的第一行,因为初始化动作必须要先执行。
如下代码所示:
/*
this的实例。
this:哪个对象调用那个方法,this就代表那个对象
*/
class Student {
private String name;
private int age;
public String getName() {
return name; //这里其实是隐含了this
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class StudentTest2 {
public static void main(String[] args) {
//创建一个对象
Student s1 = new Student();
s1.setName("欧阳");
s1.setAge(27);
System.out.println(s1.getName()+"---"+s1.getAge());
//创建第二个对象
Student s2 = new Student();
s2.setName("黄祥");
s2.setAge(30);
System.out.println(s2.getName()+"---"+s2.getAge());
}
}
五、Static关键字
1、static的特点
①static是一个修饰符,用于修饰成员。
②static修饰的成员被所有的对象所共享。
③static优先于对象而存在,因为static的成员随着类的加载就已经存在了。
④static修饰的成员多了一种调用方式,就是可以直接被类名所调用,类名.静态成员。
⑤static修饰的数据是共享数据,对象中存在的是特有数据。
2、static关键字注意事项
①在静态方法中不能使用this或者super关键字。
②静态方法只能访问静态的成员变量和成员方法。(非静态既可以访问静态也能访问非静态)
③主函数是静态的。
3、成员变量和静态变量的区别
①两个变量的生命周期不同
- 成员变量随着对象的创建而存在,随着对象的回收而释放。
- 静态变量随着类的加载而存在,随着类的消失而消失。
- 成员变量只能被对象调用。
- 静态变量可以被对象调用,还能被类名调用。
④成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据;静态变量数据存储在方法区(共享数据),所以也叫对象的共享数据。
4、主函数main解析
①主函数的特殊之处:格式是固定的;被JVM所识别和调用。主函数:public static void main (String[] args)
- public :因为权限必须是最大的。
- static:不需要对象的,直接用主函数所属类名调用即可。
- void:主函数没有具体的返回值。
- main:函数名,不是关键字,只是一个被JVN所识别的固定的名字。
- String[] args:这是主函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型。
5、静态何时使用?
①静态变量a、当分析对象中所具备的成员变量的值都是固定的,这时这个成员就可以使用静态修饰。
b、只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的。
c、如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中,定义成静态的。
②静态方法
a、函数是否用静态修饰,就参考一点,就是该函数的功能是否有访问到对象中特有数据。
b、简单的说,从源代码看,该功能是狗需要访问到非静态的成员变量,如果需要,该功能就是非静态的;如果不需要,该功能就可以定义成静态的。
c、但是,非静态需要被对象调用,而仅创建对象调用非静态的,没有访问特有数据的方法,该对象的创建是没有意义的。
静态方法代码示例:
/*静态变量代码示例:
静态方法
*/
class Teacher {
public int num = 10;
public static int num2 = 20;
public void show() {
System.out.println(num); //隐含的告诉你访问的是成员变量
System.out.println(this.num); //明确的告诉你访问的是成员变量
System.out.println(num2);
//function();
//function2();
}
public static void method() {
//无法从静态上下文中引用非静态 变量 num
//System.out.println(num);
System.out.println(num2);
//无法从静态上下文中引用非静态 方法 function()
//function();
function2();
}
public void function() {
}
public static void function2() {
}
}
class TeacherDemo {
public static void main(String[] args) {
//创建对象
Teacher t = new Teacher();
t.show();
System.out.println("------------");
t.method();
}
}
/*
静态变量示例
*/
class Student {
//非静态变量
int num = 10;
//静态变量
static int num2 = 20;
}
class StudentDemo {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.num);
System.out.println(Student.num2);//静态可通过类名调用。
System.out.println(s.num2);//静态变量也可以通过类名调用。
}
}