1.1 万物皆对象
问题:我们是怎么认识世界的?
人类从就不断的接触世界上各种各样的事物(动物、植物、建筑、山川、河流.....),然后通过这些事务的公共属性,归纳出这些事务的共同特征。所以,当我们见到猫的时候,不会叫老虎,见到树木的时候,不会叫花朵。我们在现实生活中,是通过具体的某种事物归纳总结它们的公共特性然后产生类(一类事物)。那么类就描述了该种事物的的共性。类相当于造事物的图纸,我们可以根据这个图纸去做出具体的实体对象。
问题:说一说教室里的对象?
学生 桌子 椅子 电脑 电视
对象:在现实生活中存在具体的一个事物。
类:实际就是对某种类型事物的共同属性与行为的抽取。
人类认识世界:对象----à类。
在java中: 类 -----à对象。
1.2 面向对象概述
“面向对象”(英语:Object Oriented,简称OO)是一种以事物为中心的编程思想。
面向对象程序设计(英语:Object-oriented programming,缩写:OOP),是一种程序开发的方法。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。
面向对象是相对于面向过程而言的(c则是一个典型的面向过程的语言),站在面向对象的角度去看问题,你则是对象的动作的指挥者。如果站在面向过程的角度去看问题,你则是动作的执行者。
1.3 面向对象和面向过程的对比
“面向过程”强调的是功能行为,面向过程”是一种以过程为中心的编程思想。“面向过程”他们不支持丰富的“面向对象”特性(比如继承、多态),就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。面向过程在这一系列工作的执行中,强调的是工作的执行。
1:买电脑
面向过程
1:查资料
2:电脑城砍价
3:被黑
4:痛苦归来
面向对象
1:找对象(老师)
2:老师.砍价
3:老师.检测电脑
4:电脑成功购买
2:吃饭
面向过程
1:自己动手做
2:买菜
3:洗菜
4:煮饭炒菜
5:很难吃,浪费时间
面向对象
1:找专业对象(餐馆)
2:餐馆.点餐
3:餐馆.做饭
4:饭好吃,节约时间,精力
3:找对象
面向过程:
1:上网聊天
2:约见面
3:请吃饭
4:......
5:发现不合适,分手,很痛苦!
面向对象:
1:求介绍,相亲,找现成的对象。(面向对象的思想先找有的对象,直 接拿来使用)
2:不满意,没有对象,自己造一个。(sun没有提供,自己造对象)
1.4 对象
对象(object)代表现实世界中可以明确标识的一个实体。例如:一个学生、一张桌子、一间教室,一台电脑都可以看做是一个对象。每个对象都有自己独特的状态标识和行为
对象的属性(attribute,或者状态(state)),学生有姓名和学号,该学生特有的姓名和学号就是该学生(对象)的属性。
对象的行为(behavior),是由方法定义,调用对象的一个方法,其实就是给对象发消息,要求对象完成一个动作。可以定义学生对象具备学习的行为。学生对象可以调用学习的方法,执行学习的动作。
1.5 类
****** 类是对对象所应当具有的特征的描述。
类是抽象的存在。
对象是具体的存在。*********
在java中,对象对应着内存中的一片数据。
1.6 类与对象的关系:
类好比是图纸,对象好比是房子。
类存在的理由:可以通过这个图纸,创建多个房子。
****** 类创建对象的的过程叫做:实例化*********
1.7 java开发的任务
使用已有的类创建对象。(jdk中提供的)
编写自已的类,使有自已的类创建对象。
调用对象的方法,属性,去解决问题。
1.8 类的定义与使用
1.8.1 使用已有的类
Java API提供了一些现成的类供我们使用,我们可以使用这些现有类来创建实例(对 象),比如:
String
Object
包装类Integer、Long…
集合类等等
使用现有类创建对象
**********类名对象引用变量名= new 类名 ();*********
例如:
String s1 = new String(“Hello,World”);
Object o = new Object();
1.8.2 自定义类
除了使用现有API提供的类库,我们也可以自定义类。之前我们说过类是具有相同属性和相同操作的对象集合,属性就是成员变量,操作就是方法。
所以,类的定义主要有两方面组成
成员变量(属性)
方法(行为)
格式
class 类名{
成员变量(属性)定义;
方法定义;
}
约定俗称的命名规则
************类名的首字母大写
变量名和方法名的首字母小写
采用驼峰命名标识***************
userName useruame
userAge studentName studentAge
stuDent(错误举例) student
1.9 属性
类的定义主要由属性和方法组成。属性是指类(这类事物)拥有的特征。属性,通常是名词。
例如:定义一个学生类,拥有的属性有:学号,姓名,年龄,家庭住址...
那么如何确定一个类拥有哪些属性(特征)?其实,一个类(一类事物)拥有的属性有很多种。通常,我们在定义类的属性时,遵循的原则是,需要什么属性就定义什么属性。
定义属性的语法:
[访问控制符] 数据类型 属性名 [=值]
class Student{
int num; //学号
String name; //姓名
int age; // 年龄
String address; //家庭住址
...
}
1.10 方法
类的另一个成员,方法(动词)。方法,指一个类的行为(动词)。
方法的四个要素:
1、访问控制符
2、返回值类型------------返回值(方法调用结束之后,返回给调用者的信息) void(方法没有返回值)
3、方法名------调用的时候用来区分
4、参数列表-------------参数--方法运行时,需要的额外的信息.方法有返回值,在方法中就一定要有return
无参数,无返回值的方法:
在学生类(Student)中添加学习(study)方法,和玩游戏(playGame)方法
public void study(){
System.out.println(“努力学习”);
}
public void playGame(){
System.out.println(“开心玩游戏”);
}
无参数,有返回值的方法:添加自我介绍的方法introduce
public String introduce(){
return “我叫”+name;
}
有参数的方法:
为什么要用带参数的方法?
public class ZhaZhiJi{
public String zhazhi (String fruit ) {
String juice = fruit + "汁";
return juice;
}
}
向学生类中添加做整数加法题的方法:
public int add(int x,int y){
int result = x+y;
return result;
}
1.11 创建实例
类创建对象的过程叫做实例化。
Java中实例化对象和数组相同,也是使用new关键字。
语法:
类名对象名= new 类名();
Student stu = new Student(); 创建一个Student类的对象实例(可以简称为创建一个Student类的对象),对象的名字叫做stu(对象名,通常叫做对象引用)。
Student stu2 = new Student();// 又创建了一个Student对象,对象的引用叫做stu2
Student stu3 = stu;
内存分配图景:
案例1:定义一个计数器类,功能包括:走一步,读取数字,清空。创建对象并测试。
public class JiShuQi {
int num = 0;
//走一步
public void run() {
num++;
}
//读取
public int read() {
return num;
}
//清空
public void clear() {
num = 0;
}
public static void main(String[] args) {
JiShuQi jsq = new JiShuQi();
jsq.run();
int read = jsq.read();
System.out.println(read);
jsq.run();
jsq.run();
int read2 = jsq.read();
System.out.println(read2);
jsq.clear();
System.out.println(jsq.num);
}
案例2:定义一个汽车类,并生产出汽车,有颜色,轮胎个数,有运行的功能。
public class Car {
String name;
String color;
int geshu;
public String run() {
return "汽车正在路上跑";
}
public static void main(String[] args) {
//造车
Car c = new Car();
c.name = "拉博基尼";
c.color = "白色";
c.geshu = 4;
String run1 = c.run();
System.out.println("我的车造好了名字叫" + c.name + "颜色是" + c.color + "轮胎有"
+ c.geshu + "个" + run1);
}
分析:如何描述现实世界中的事物,描述该事物的属性和行为,汽车具有颜色和轮胎数的属性,具备运行的行为。
如何使用Java语言进行转换?
根据对应关系:
属性:类中的成员变量
行为:类中的成员方法
那么定义Java类就是定义一个类的成员。汽车类具备的成员是:颜色,轮胎数,运行方法。
Car类定义流程:
1. [endif]使用class 关键字 定义类,
1. [endif]class空格 类名。类名就是标识符,命名规则,单词的首字母大写,多个单词的首字母大写。注意:不是规定,但是最好遵守
2. [endif]类名后紧跟一对{}表示类的开始和结束。
2. [endif]汽车有轮胎数int num;
1. [endif]不需要给num初始化值,因为汽车轮胎数不确定,有4,有6,有8。
3. [endif]有颜色 String color
1. [endif]为什么使用String 例如定义颜色"红色"是字符串类型。
2. [endif]也不需要初始化值。
4. [endif]跑的行为(方法、函数) void run(){}
1. [endif]方法中执行输出语句。syso("跑啦。。。。");
作业:定义一个学生类属性(学号,姓名,年龄,性别)方法(学习,做整数加法)
定义一个5个长度的数组创建5个Student对象,存入数组中。
变量数组,分别输出5个Student对象的各个属性的值
int id;
String sname;
int age;
char sex;
public void XueXi() {
}
public int add(int x, int y) {
int result = x + y;
return result;
}
public static void main(String[] args) {
Student stu1 = new Student();
stu1.id = 001;
stu1.sname = "德玛西亚";
stu1.age = 22;
stu1.sex = '男';
Student stu2 = new Student();
stu2.id = 002;
stu2.sname = "比尔吉沃特";
stu2.age = 22;
stu2.sex = '男';
Student stu3 = new Student();
stu3.id = 003;
stu3.sname = "诺克萨斯";
stu3.age = 22;
stu3.sex = '女';
Student stu4 = new Student();
stu4.id = 004;
stu4.sname = "苏瑞玛";
stu4.age = 22;
stu4.sex = '男';
Student stu5 = new Student();
stu5.id = 005;
stu5.sname = "扭曲丛林";
stu5.age = 22;
stu5.sex = '男';
Student[] aa = new Student[]{stu1,stu2,stu3,stu4,stu5};
for (int i = 0; i < aa.length; i++) {
System.out.println("学号:"+aa[i].id+"姓名:"+aa[i].sname+",年龄:"+aa[i].age+",性别:"+aa[i].sex);
}
}
作业2:定义一个Car类,属性(车名,颜色,轮子,车型)方法 run
定义一个修车的工厂类CarFactory 修车的方法 对车进行修理
比如说一辆车丢了一个轮子,去工厂修理,提醒我是否修理成功
解:
第一个class文件:
//需要的汽车属性
public class Car01 {
String name;
String color;
int sum;
String cx;
public int run(){
//汽车运行后,返回一个轮胎数丢一个
return sum-1;
}
public static void main(String[] args) {
//制造汽车
Car01 c=new Car01();
c.name="大黄蜂";
c.color="黄色";
c.sum=4;
c.cx="赛博坦机器人";
//取到汽车运行后轮胎数的属性
int sum=c.run();
//运行后汽车轮胎数赋给rsum
int rsum=sum;
System.out.println(rsum);
//
CarFactory c2=new CarFactory();
//修车后的结果
String jg=c2.xiuChe(c);
System.out.println(jg);
}
第二个class文件
public class CarFactory {
//修理汽车(车子的轮胎数决定是否需要修理),将坏的汽车送到修理厂,将Car01 c作为参数传给修车厂
public String xiuChe (Car01 c){
int sum=c.sum;
if(sum>=4){
return "车子没毛病";
}else{return "车子修好了";}
1.12 对象成员的调用
有了car对象,调用对象成员
[if !supportLists]1. [endif]成员变量
[if !supportLists]2. [endif]成员方法
使用点(.)来调用
1.13 成员变量和局部变量
成员变量:定义在类中的变量。
局部变量:定义在方法中的变量和方法的参数。
成员变量与局部变量的区别:
1. [endif]应用范围
1. [endif]成员变量在整个类内都有效
2. [endif]局部变量只在其声明的方法内有效
2. [endif]生命周期
1. [endif]成员变量: 它属于对象,它随着对象的创建而创建,随着对象的消失而消失。被同一个类中的方法共享。
2. [endif]局部变量: 使用完马上释放空间。(定义它的那一对{}),另外,局部变量,定义完成后,必须赋初值。
1.14 面向对象练习
完成汽车修理功能。
汽车类(Car)和修理厂类(Factory)
Car的属性和方法:
属性:名字、颜色、轮胎数量
方法:跑。方法要求:如果汽车的轮子数量少于4个则显示汽车不能正常运行,如果是4个汽车则可以跑起来。
Factory的属性和方法。
属性:名字、地址
方法:修理汽车(修理汽车的轮胎数量)
编写汽车类、修理厂类和测试类。
1.15匿名对象
匿名对象:没有名字的实体,也就是该实体没有对应的变量名引用。
匿名对象的用途
1,当对象对方法进行一次调用的时候,可以使用匿名对象对代码进行简化。
为什么只对方法,而不调用属性呢?因为匿名对象调用属性没意义。
如果对象要多成员进行多次调用,必须给对象起个名字。不能在使用匿名 对象。
2,匿名对象可以实际参数进行传递。
匿名对象的简单演示
1:new Car().run();
内存结构图
1:new Car().num=5;
2:new Car().clor="blue";
两个new是两个不同的对象,在堆内存中有不同的空间,相互不相互干扰。
匿名对象的使用
1:当只使用一次时可以使用匿名对象。执行完毕到;后该对象就变成了垃圾。
new Car().run();
2:执行方法时,可以将匿名对象作为实际参数,传递进去。
修黑车
1:需求
将小汽车改装成3个轮子的黑车。
1:汽车类。
2:汽车修理厂
/*
匿名对象
匿名信
修黑车
汽车类
黑车厂类
把汽车的改成黑色3轮车。
*/
class Car {
String name = "smart";
String color = "red";
intnum = 4;
void run() {
System.out.println(name + ":" + color + ":" + num + ":跑起来了。。。。");
}
}
class BlackCarFactory {
String name;
String addr;
Car repairCar(Car c) {
c.num = 3;
c.color = "黑色";
System.out.println("改装成功啦。。。");
}
}
class Demo1 {
publicstaticvoid main(String[] args) {
BlackCarFactory bcf = new BlackCarFactory();
bcf.name = "幸福修理厂";
bcf.addr = "北京市海淀区中关村软件园汉王大厦";
//非匿名对象
Car c = new Car();
c.run();
//改装
bcf.repairCar(c);
//取车
c.run();
//匿名对象一,只使用一次:
//如下创建了2个对象
/*
* new Car().run();
*
* new Car().run();
*/
//匿名对象二,作为实际参数传递
Car c2 = bcf.repairCar(new Car());
c2.run();
System.out.println();
}
}
1.16 形参和实参
形参:形式参数(声明方法时,方法中声明的参数)=
实参:实际参数(调用方法时,实际传给方法的参数)
形参的改变,不会影响实参
2 封装
面向对象的三个基本特征(封装、继承、多态)
2.1 为什么要封装
我们日常使用的电脑主机,把cpu、内存、主板等等都封装到机箱里面去。假如没有机箱的话的出现什么问题,主机、主板全部都散落在一处,然后开机没有开机按钮,那么需要我们直接操作接跳线才能把电脑开启。这样子的话假如操作不慎的话,会让机器损坏危险,那么假如用机箱封装起来的话,那么就不需要这样子做了。体现了封装的---安全特性。
你拿电脑去加内存,可以直接给电脑给维修的人,等他加好内存了之后。你拿到的还是那个机箱,里面发生了怎样子的变化你并不知道。封装的第二个好处-将变化隔离。
在机箱里面提供一个开机按钮,而不需要你直接使用跳线开机的话,体现了封装的—便于使用的特性。
只要机箱提供了一个开机的功能,然后无论这个机箱拿到哪里去,都可以使用这个开机的功能.体现了封装的---提供重复性的特性。
不使用封装的问题:学生类,年龄赋值问题。
2.2 如何封装
Java中,使用private关键字对属性进行封装。
封装后的属性将不能直接访问?那么如何访问?
每个被封装的属性,都应该提供相应的set和get方法(setter/getter)
案例:定义学生类,属性包括:学号,姓名,年龄,性别,地址。封装这些,属性,并提供相应的setter和getter。
2.3 封装的好处
1:隐藏了类的具体实现
2:操作简单
3:提高对象数据的安全性
3 构造方法
又称为构造器、构造函数
C++称为构造函数。
Java中称为构造方法或构造器。
构造方法是一个对象刚刚出生时,调用的第一个方法。(出生的洗礼)
它一般从事一些初始化的工作。
3.1 构造方法的特征
名字必与类名相同。
参数可有可无,可多可少。
没有返回值,也不是void。
new 的时候被自动调用。
3.2 构造方法的作用
构造方法作用:对对象进行初始化
案例:我们人出生的时候,有些人一出生之后再起名字的,但是有些人一旦出生就已经起好名字的。那么我们在java里面怎么在对象一旦创建就赋值呢?
定义Person类型,属性有名字和年龄,使用构造方法,完成初始化对象时,给名字和年龄赋值的工作。
3.3 构造方法细节
1. 当类中没有定义构造函数时,系统会指定给该类加上一个空参数的构造函数。这 个是类中默认的构造函数。当类中如果自定义了构造函数,这时默认的构造函数就没有了。
2.在一个类中可以定义多个构造函数,以进行不同的初始化。多个构造函数存在于类中,是以重载的形式体现的。因为构造函数的名称都相同。
3.4 初始化代码块
类似构造方法,也是用来初始化对象的成员变量的,是类里面可以定义的第四种成员。(前三种依次是成员变量、方法和构造方法)
格式:
class 类名{
{
初始化块;
}
}
构造函数已经能初始化对象了为什么还要有初始化块啊?
初始化块初始化对象的时期优先于构造函数,所以当多个构造函数拥有同样的初始化语句时,可以把该语句统一提到初始化块中定义,以免相同的初始化语句分散到各个构造函数中引起代码重复、凌乱。
class Boy {
String name;
Int age;
String gender;
//构造代码块,给所有对象进行初始化。
{
System.out.println("哭。。。");
}
Boy() {
System.out.println("无参构造");
}
Boy(String n, int a, String g) {
name = n;
age = a;
gender = g;
System.out.println("有参构造");
}
void run() {
System.out.println("跑...");
}
}
4 this关键字
this,当前对象的默认引用。(调用这个方法的对象的引用)
作用:
1、调用成员变量,用来解决成员变量和局部变量同名的问题。
2、调用方法,简化代码编写(IDE工具代码提示功能)。
3、在构造方法中调用其他构造方法。(注意:在构造方法中调用其他构造方法时,this语句必须方法在第一句)
5 方法重载(overload)
方法重载是指,在同一个类中,方法名相同,参数列表不同的方法。(与方法的访问控制符和方法的返回值类型无关)
5.1 为什么要重载
为了节约词汇,把相近的概念用相同的词汇表达。这们便于记忆,可以根据参数的类型来区分是哪个方法。
5.2 重载的列子
class 电视机{
…
public void 换频道(int x){ … }
public void 换频道()
…
}
x.换频道();
x.换频道(8);
以下哪些是方法重载?
5.3 构造方法重载
6 static关键字
static关键字可以用于修饰类的成员变量、方法和初始化代码块。
static修饰的变量称为静态变量。
static修饰的方法称为静态方法。
static修饰的初始化代码块,称为静态初始化块。
6.1 静态变量
用static修饰的变量叫做静态变量(类变量)。
静态变量的特征:类的所有对象共享同一个静态变量。
例如:static int x
6.2 静态方法
static修饰的方法叫做静态方法(类方法)。
调用方式:可以通过对象调用,也可以通过类名直接调用
例如:public static void hello(){}
6.3 静态初始化块
static 修饰的初始化块
特征:在类加载时,只会执行一次
例如:static{}
案例1:使用static 完成 投票功能。
最多有5个人投票,定义投票人的类(voter),
在这个类中定义一个投票的方法,当票数超过5时,提示不能再投票。
public class Voter {
private static int n;
public void vote(){
if(n>=5){
System.out.println("票数已满");
}else{
n++;
}
}
}
案例2:使用计数器num统计创建Student对象的个数(提示构造方法里对num进行自加操作)
案例3: 定义一个数组操作的工具类,MyArrays。方法包括:
最大值,最小值,升序排列,求和方法
6.4 static特征总结
1 静态方法中不能访问非静态成员变量和成员方法(非静态方法可以方法静态变量)
2 静态方法中不能使用this关键字
3 随着类的加载而加载,静态会随着类的加载而加载,随着类的消失而消失。说明它的生命周期很长。
4 优先于对象存在。-->静态是先存在,对象是后存在。
5 被所有实例(对象)所共享。
6 可以直接被类名调用
静态变量(类变量)和实例变量(new)的区别:
1存放位置
1:类变量随着类的加载而加载存在于方法区中.
2:实例变量随着对象的建立而存在于堆内存中.
2生命周期
1:类变量生命周期最长,随着类的消失而消失.
2:实例变量生命周期随着对象的消失而消失.
静态优缺点
1: 优点:对对象的共享数据进行单独空间的存储,节省空间
2:缺点:生命周期过长
访问出现局限性。(静态只能访问静态)
什么时候定义静态变量
1:静态变量(类变量)当对象中出现共享数据
例如:学生的学校名称。学校名称可以共享
对象的数据要定义为非静态的存放在对内存中(学生的姓名,学生的年龄)
什么时候定义静态方法
如果功能内部没有访问到非静态数据(对象的特有数据。那么该功能就可以定义为静态)
6.5 单例模式
23种设计模式中的一种
一些人总结出来用来解决特定问题的固定的解决方案。
解决一个类在内存中只存在一个对象,想要保证对象的唯一。
1 为了避免其他程序过多的建立该类对象。禁止其他程序建立该类对象。
2 为了其他程序可以访问该类对象,在本类中自定义一个对象。
3 方便其他程序对自定义类的对象的访问,对外提供一些访问方式。
代码:
1将构造函数私有化
2在类中创建一个私有的本类对象
3提供一个用类名调用的公有方法获取该对象。
class Single {
private static Single s = new Single(); // 饿汉式
private Single() {
}
public static Single getInstance() {
return s;
}
}
class Single2 {
private static Single2 s = null; //懒汉式
private Single2() {
}
public static Single2 getInstance() {
if (s == null) {
s = new Single2();
}
return s;
}
}