复习
1.Java有多少种数据类型,数据类型的分类?
2.Java的工作机制?
3.自定类型转换与强制类型转换的规则?
4.什么是变量,如何定义变量?
5.整型从小到大排序并且说出大小?
6.++与--放在变量前面与后面的区别?
7.解释一下&&与||的作用?
8.基本数据类型的包装类型分别是什么?
9.请解释一下==?
10.JDK&JRE&JVM分别是什么以及他们的关系?
前言
总听人说“面向对象编程”(OOP,Object Oriented Programming),
那么什么是对象?是找对象的对象吗?
与面向对象相对应的是又是什么?什么是类?学Java很累吗?什么是实例化?
今天为大家揭开面向对象的神秘面纱。
本节课只介绍一些基础的面向对象知识,所以是初级版,后面还会继续为大家介绍进阶版。
“面向对象”的知识体系包括:封装、继承、多态、抽象类、接口、重写、重载等等概念。
本节课的概念必须100%掌握,以后对后面的学习非常重要,因为知识是一环套一环的,
一步跟不上,步步跟不上。本节课主要有四大核心概念:类、对象、方法、属性。
对象与类
首先对象并不是找对象的对象。。。这块知识点注重的是理解,而不是死记硬背。
我们需要从思维&思想方式上进行转变,开始学着用面向对象的思维去分解&分析问题。
对象(object)
对象是用来描述客观事物的一个实体&个体,例如:一张银行卡、一个客户、一个人、一条狗等,
每个实体都具有自己的状态(状态是名词,例如:身高、体重、年龄等)。
每个试题都具有自己的行为(行为是动词,例如:吃饭、睡觉、打豆豆)。
每个对象都有自己的唯一标识,即使两个对象的状态与行为完全一致,
对象在内存中的存储也会不同。
注意:在Java中,对象、实例、实例对象,说的是一个东西,他们的概念相同,就像孔明与诸葛亮。
类(class)
我们把一类&一些&一堆&一组事物(实体&个体)中相同的部分(相同的行为&相同的状态)抽出来,
形成一个抽象的模板,模版是对这一类事物的描述(描述一类事物的行为和状态),
这个模板就是类(类是创建对象的模板)。
强化理解:
三个不同的人都具有各自的身高、体重、年龄这三项状态,都具有吃饭、睡觉、打豆豆这三项行为,
那我们可以把这三个人相同的状态与行为抽出来,形成一个“人类”。
大白话理解:
把相似的事物(对象)归成一类。。。
类的Java语法(需要背)
[修饰符] class 类名{
}
public class Person{
}
修饰符的作用是修饰类,不同的修饰符表达不同的含义,暂不展开细节,
类只能被修饰成:public、abstract、final以及什么都不写(内部类除外,细节暂不展开)。
class是类的关键字,Java中就规定这么用,别问为什么。
类名:首字母大写,大括号保住的部分叫类体,就是类的内部,类的内部可以有方法和属性等元素。
一般一个Java文件中只有一个类,类名与Java文件的名字保持一致,
可以理解成Java程序是由n个类组成的。
类的格式
![](https://i-blog.csdnimg.cn/blog_migrate/db3082d88ccc0e926a22e0eacb41d412.png)
上面的例子是让大家先熟悉一下类的基本结构,下面让我们来定义一个狗类
class Dog{
String type;
int age;
static String color;
static void barking(){
System.out.println("汪汪汪!!!");
}
void hungry(){
System.out.println("我好饿!");
}
void sleeping(){
System.out.println("Zzzz,我在睡觉");
}
}
System.out.println();表示输出语句到控制台。
System是一个Java提供的系统,out是标准输出对象,是类变量(对象),println()是实例方法。
访问实例变量和方法,使用" ." 来访问,使用"="来赋值,使用";"来结束一条语句。
Dog d1 = new Dog();
d1.age = 3;
d1.sleeping();
Dog d2;
d2 = new Dog();
d2.age = 8;
d3.hungry();
类与对象的关系
类与对象的关系是抽象与具体的关系。
类是对象的抽象,对象则是类的实例。
类的作用是用来创建对象的,每个对象都是类的一个实例。
一个类可以有0-n个对象(最少0个,最多n个)。
在类中可以定义0-n个状态以及0-n个行为,每个不同的对象都可以允许有属于自己的状态。
(10个人各自都有自己的名字)
![](https://i-blog.csdnimg.cn/blog_migrate/2d293347f4a088060dff1fad7b41b11f.png)
状态、行为是现实中的叫法,在Java中的叫法变成了属性、方法;
行为->方法
状态->属性(属性就是后面要讲的成员变量,成员变量包括类变量与实例变量两种)
对于新手玩家的你来说,目前只要记住类里只需要定义属性和方法即可,后面的知识点会陆续展开。
实例化
:创建对象的过程。一个Person类,可以创建多个person对象(对象等于实例),
而这个“造人”的过程,被称为实例化 。
抽象
:创建类的过程。多个person对象,如果他们的状态和行为类似,
那么我们可以将相同的行为与状态抽出来,形成一个Person类,
这个过程被称为抽象,与实例化相反。
例如:
一个人(terry)是一个对象,
他的状态是:名字(terry)、体重(70kg)、年龄(30),他的行为是:吃饭、睡觉、打豆豆。
一个人(jack)是一个对象,他的状态是:名字(jack)、体重(80kg)、年龄(33),
他的行为是:吃饭、睡觉、打豆豆。
一个人(alex)是一个对象,他的状态是:名字(alex)、体重(60kg)、年龄(30),
他的行为是:吃饭、睡觉、打豆豆。
(可以发现每个人的状态里具体的值可能不一样,也可能一样,但行为都一样。)
这三个对象都具有共同的状态和行为,那么我们就可以针对这三个对象的共同点抽象出来一个类。
这三个人都属于"人"类,"人"类定义了人的概念(状态与行为),
人类是抽象的,看不见摸不着的,只是一个模板。
而人则是真实存在的,有血有肉的个体(实例),有不同的状态和相同的行为。
在Java的世界中,你不是人类,你只是人,你是人类的一个个体,也叫做对象或实例。
请看下面的例子,男孩类与女孩类,而具体的每个人则是类的对象。
![](https://i-blog.csdnimg.cn/blog_migrate/f00b90b7f41d50fc4acc32311b82525e.png)
生活中的类与对象
举一反三,现实生活中还有非常多的关于类与对象的身影,例如:
猫类(状态:颜色,名字,性格;行为:睡觉,挠爪子,吃饭)
一只波斯猫对象 (状态:红色,kitty,爱挠人;行为:睡觉,挠爪子,吃饭 )
汽车类(状态:颜色,轴距,价格;行为:刹车,开空调,听音乐)
一台宝马320LI对象 (状态:白色,1600,32万;行为:刹车,开空调,听音乐 )
大家思考一下,还能举出来一些其他的例子吗?
创建对象(对象的实例化)
对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。
创建对象需要以下步骤:
1.声明:声明一个对象变量,包括变量名称和变量的数据类型(我们的类就是引用数据类型)。
2.实例化:使用关键字new来创建一个对象,使用new创建对象时,会调用构造方法初始化对象。
3.赋值:将新new出来的对象赋值给了刚刚声明的对象变量。
通常我们会把这三步使用一条语句写出来,类似于Person p = new Person();
实例化语法
类名 变量名 = new 类名();
public class ClassDemo1 {
public static void main(String[] args) {
/**
* 其中Person为类名,p1为对象变量名,Person()则是调用Person类的无参构造方法。
* new运算符为对象分配内存空间,它调用构造方法,返回Person对象。
*(术语是返回Person对象的引用,新人可以暂忽略,这涉及到java堆栈内存)
* 再将Person对象赋值给数据类型为Person的变量p1。
* 一个类的不同对象,分别占据不同的内存空间,如果肆无忌惮的new,会导致内存溢出的风险。
*/
Person p1 = new Person();
//使用"."来调用对象的属性与方法。
p1.age = 14;
p1.name = "张三";
p1.eat();
p1.sleep();
}
}
class Person{
String name;
Integer age;
public void eat() {
System.out.println(name+"在吃饭.");
}
public void sleep() {
System.out.println(name+"在睡觉.");
}
}
Person p1 = new Person();可以拆成2个步骤
步骤1
Person p1;
声明一个数据类型为Person的变量,这个变量的名字叫p1。
Person是数据类型(这个是自定义的引用数据类型,程序员自定义的类也可以做为数据类型)。
步骤2
p1 = new Person();
将数据类型为Person的变量p1赋值,赋的是一个Person对象(Person对象的引用)。
new Person();这就是在实例化,把Person类实例化成一个Person对象。
之后将这个新创建的Person对象赋给了p1变量。
匿名对象
创建完对象,在调用该对象的方法时,也可以不声明对象,而直接调用这个对象的方法。
这样的对象叫匿名对象。
new Person().eat();
如果对一个对象只需要进行一次方法调用,可以使用匿名对象。
(plus一个Java程序员的梗:过情人节没有对象陪,就自己new一个对象。 )
方法(method)
很多人喜欢把方法叫成函数,一个类可以有很多方法。方法是完成某个功能的一组语句,
逻辑运算、数据修改以及其他业务逻辑动作都是在方法中完成的。
方法的Java语法
![](https://i-blog.csdnimg.cn/blog_migrate/ffb9cc300dd85eb1fa5b73bb74859059.png)
修饰符
这是可选的,告诉编译器如何调用该方法,定义了该方法的访问类型。
最常见的是static,如果有static则定义为类方法,直接使用类名即可调用。
没有static则是实例方法,必须由对象调用。
public是访问权限控制符,在后面的章节会详细介绍,暂不展开。
方法的修饰符还有很多,例如:synchronized、final、private、protected等等,暂不展开。
返回类型
方法可能会返回值,什么是返回值呢?就是方法执行完的结果要返回给调用方的意思。
而返回类型就是方法要返回的结果的数据类型。在本例中String是方法返回值的数据类型。
当然方法也允许没有返回值,我们使用关键字void。
返回值
方法在执行完毕后把一些数据返回给方法的调用者。
例如:方法的调用者需要得到一些该方法运行结束后的若干信息,
医生让患者去做X光,做X光相当于是方法,而医生相当于是方法的调用者,
调用了患者对象的做X光方法,X光方法执行完毕后,需要将X光照片返回给医生,
医生拿着照片需要做诊断治疗,那这个X光照片就是返回值。
如果有返回值则需要设置返回类型+返回值,使用return关键字。
遇到return语句,方法结束执行,后续语句不执行。如果没有返回值,则需要设置返回类型为void。
当然在void的情况下,也可以直接写一个return语句让程序快速跳出当前方法。
方法名
是方法的实际名称,调用方法时需要知道方法的名字,一般遵守小驼峰命名规则。
参数列表
参数像是一个占位符,当方法被调用时,调用方需要传递值给参数,参数可以有0-n个。
参数列表包含参数类型、形式参数(简称形参,在方法被调用时用于接受外部传入的变量)、
形式参数的数据类型、顺序和参数的个数。
方法体
方法体包含具体的语句,定义该方法的功能。
例如:
我现在要在Person类中定义一个吃饭的方法
public class Person{
public void eat(String name){
System.out.println(name+"在吃饭哟");
}
}
方法调用
方法和类都定义好之后,我需要调用了对吧?那我再写一个主函数去调用它。
public static void main(String[] args){
Person p1 = new Person();
String nameA = "张三";
p1.eat(nameA);
}
控制台会输出:“张三在吃饭哟”,这里的nameA叫实际参数。
方法中参数列表的参数叫形式参数,简称形参。
方法外声明的变量,作为参数传递到方法里的参数,叫实际参数,简称实参。
(这里衍生出一个概念,叫java值传递,有兴趣的童鞋可以去搜一下,
为什么java只有值传递,没有引用传递?)
方法的种类
1.实例方法
属于每个实例的方法,必须使用对象来调用,方法前不要加static修饰。
2.类方法
类方法也叫静态方法,属于类的方法,必须加static修饰,使用类名调用。
(当然类方法也可以使用实例调用,但是不建议这么做),
为什么要用类名来访问一些方法呢?因为不耗费内存,不用创建实例。
类方法中,只能调用类方法与类变量,不能调用实例方法与实例变量。
实例方法中,允许调用类方法与类变量。
3.构造方法/构造器(Constructor)
构造方法是一个类创建对象的根本途径,如果一个类没有构造方法,这个类通常无法创建实例。
因此如果程序员忘记定义构造方法的话,Java编译器将会为该类提供一个默认构造方法,
该方法为无参的构造方法,一旦程序员已经定义了构造方法,则系统不再提供默认的构造方法。
(注意:如果程序员定义了一个有参构造,系统也不再提供默认的无参构造)
构造方法的作用
通过new关键字来调用某个类的构造方法,即可创建这个类的实例。
在创建一个对象的时候(类实例化成对象的时候),至少要调用一个构造方法。
构造方法的作用是完成对象的创建,即完成对象的实例化,
在构造方法中一般可以对成员变量进行初始化操作。
构造方法的特点
1.构造方法的名称必须与类同名;
2.一个类可以有多个构造方法(参数列表不同);
3.构造方法没有返回类型,不能return;
4.构造方法可以设置为private即在外部无法调用该类的构造方法,这是所谓的单例模式,
关于private等访问控制符会在介绍封装的时候详讲,关于单例模式可参考设计模式系列文章。
构造方法的使用
public class Puppy{
int age;
String name;
public Puppy(){
System.out.println("调用我了哟,我是无参构造哟");
}
public Puppy(String name){
System.out.println("这里是有参构造哟,汪汪汪"+name);
this.name = name;
}
}
Puppy p1 = new Puppy();
此时p1对象的属性没有被显式的初始化,age的默认值为0,name的默认值为null。
Puppy p2 = new Puppy("旺财");
此时p2对象的属性被有参构造初始化了,age的默认值为0,name的默认值为旺财。
千万千万不要把构造方法与普通方法混淆。
Puppy()就是构造方法里的无参构造,如果没有则会默认提供,
记住,构造方法不用写返回值,但其实返回的就是这个类的对象(类的对象的引用)。
方法的重载(overload)
方法的重载就是在同一个类中允许同时存在一个以上同名的方法。
方法名称相同,方法的参数必须不同,参数个数不同,参数类型不同,
方法的返回值类型可以相同,也可以不同。
public class Test{
public void say(String name){
System.out.println(name);
}
public void say(String name,int age){
System.out.println(name+age);
}
}
小练习:
下列关于类的定义的选项中,哪些可以通过new Thing()方法来? 创建该类的一个对象____?
A.
public class Thing {}
B.
public class Thing {
public Thing() {}
}
C.
public class Thing {
public Thing(void) {}
}
D.
public class Thing {
public Thing(String s) {}
}
E.
public class Thing {
public void Thing() {}
public Thing(String s) {}
}
this关键字
this表示调用者为当前对象,this不能作用在static的方法中。
简单记忆:哪个对象调用方法,this就代表这个对象。
官话:this代表一个引用,指向调用该方法的当前对象。
this一般使用场景:
1.使用this.方法或this.变量表示当前对象的调用。
2.使用this()表示调用当前类中的某个构造方法。
3.返回当前对象的引用。
一般情况下,在类中定义成员变量的变量名为name,方法的形参中变量名也为name,
那么通过this来区分到底是哪个name,this.name表示是当前对象的成员变量name,而非形参。
public class Person{
private String name;
public void eat(String name){
this.name = name;
}
}
属性(filed,也叫成员变量)
每个类都有各自独特的成员变量(成员变量包括类变量与实例变量),
对象的状态由这些成员变量的值来决定。
Java中有三种变量:类变量、实例变量、局部变量。
注意:java中绝对没有什么所谓的全局变量,不要被误导。
![](https://i-blog.csdnimg.cn/blog_migrate/09a4210dd4119056e9b52baf0b6a51d0.png)
类变量(也叫静态变量)
类变量在创建类的时候被初始化,表示类的属性。
类变量声明在类中,方法体之外,但必须使用static关键字来修饰。
类所有实例调用该变量时共享一块内存,可以拿类名直接调用,也可以拿对象调用(不推荐)
class Person{
static String name;//类变量
public static void main(String[] args){
Person.name = "李四";//可以直接使用类名来调用类变量
Person p1 = new Person();
p1.name = "张三";//也可以通过对象来调用类变量,但不推荐这么做
Person p2 = new Person();
p2.name = "王二";
System.out.println(p1.name);//输出王二
System.out.println(p2.name);//输出王二,因为类的所有对象的类变量都共享一块内存
}
}
实例变量(也叫非静态变量)
说明类的某一个实例的属性。
实例变量是定义在类中,方法体之外,不使用static修饰。
实例变量在创建对象的时候被初始化。
类所有实例调用该变量时都开辟一块新内存,只能拿对象调用实例变量。
class Person{
String name;//实例变量
public static void main(String[] args){
Person p1 = new Person();
p1.name = "张三";//必须通过对象(实例)来调用的变量,叫做实例变量
Person p2 = new Person();
p2.name = "李四";
System.out.println(p1.name);//输出张三
System.out.println(p2.name);//输出李四,因为类的所有对象的实例变量都开辟一块新内存,所以大家的变化不影响别人
}
}
局部变量
在方法内、代码块内、形参中定义的变量被称为局部变量。
方法、代码块结束后,变量就会自动销毁。
(所有局部变量均在方法的栈内存中存储,新手PASS)
注意:
1.除了形参以外,其他局部变量必须要初始化后才能访问;
2.局部变量的作用范围越小,它在内存里停留的时间就越短,程序运行性能就越好。
因此能用代码块局部变量的地方,就不要使用方法局部变量;
3.访问修饰符不能用于局部变量;
class Person{
{
String a = "helloworld";//代码块中的局部变量
}
public void sayAge(String name){//name为形参,也是局部变量
int age = 18;//方法内的局部变量
System.out.println(name+"的年龄是"+age);
}
}
面向过程编程&面向对象编程
从面向过程到面向对象,不仅仅是编程方式的改变,更重要的是思维方式的改变。
面向过程编程
按照顺序执行的一系列操作,我们需要先分解出解决问题的步骤,
然后用方法把这些步骤一一实现,最后依次调用方法来使得程序运行。
面向对象编程
从不同的角度来看待计算机程序,它注重的是计算机所完成的任务,而非处理方式。
从现实世界中客观存在的事物出发来构造软件系统,
并在系统构造中尽可能运用人类的自然思维方式来思考问题,
把问题中的事物分解为为系统中的对象,给对象赋予相应的属性和行为,
通过多个对象的相互协调来解决问题,对象是系统的基本构成单位。
传统的C语言属于面向过程编程,Java语言属于面向对象编程。
一些例子
面向过程编程:
1.输入密码,系统判断是否正确,如正确,进入取款界面,如错误,提示重新输入。
2.进入取款界面,输入取款金额,系统判断余额是否足够,如不足,提示;如足够,点钞。
3.吐出钞票,打印票据。
面向对象编程:
根据要解决的问题,可以抽象出如下对象:客户、银行卡、现金、票据等,
这些对象没有先后顺序,共同作用才构成了整个系统。
我们只要用代码设计出这几个类型的对象,然后让他们互相调用传递信息就可以完成系统功能。
猪八戒吃西瓜的例子:
面向过程编程:吃(猪八戒,西瓜)
面向对象编程:猪八戒.吃(西瓜)
孙悟空打白骨精的例子:
面向过程编程:打(孙悟空,白骨精)
面向对象编程:孙悟空.打(白骨精)
总结
今天我们主要学习了面向对象编程的思想转变,主要是四个重要概念:类、对象、方法、属性。
今天的概念是Java中核心中的核心,请大家务必掌握,并且知识是一环套一环的嵌套,
一步跟不上,步步跟不上,学好面向对象的思想,为以后更深的知识打好基础。
作业
创建一个人类,该类需要有定义:
名字、体重、年龄三个属性(数据类型分别为:String,Integer,Integer),
还要定义吃饭、睡觉、打豆豆三个方法。
类中需要定义有参构造,需要通过有参构造把类中的三种属性初始化。
三种方法的规则:
1.吃饭:需要传递参数,并输出"xxx在吃饭"
2.睡觉:通过前面的有参构造初始化,输出"xxx在睡觉",xxx为名字(对象的属性),方法不用定义形参。
3.打豆豆: 通过前面的有参构造初始化, 需要返回给调用者"xxx的体重是a,年龄是b",并在调用处输出。
注意:
1.xxx、a、b均为动态的,不是写死在代码里的。
2.输出的写法为:System.out.println("你好哇,这里是作业demo示例哟~~~");
需要在main方法中实例化三个人类的对象,分别设置与输出三个属性(名字、体重、年龄),
并调用三个方法,其中把打豆豆方法的返回值打印出来。