面向对象概念
所谓的面向对象(OOP,Object Oriented Programming)是一种编程思想,通过这种思想可以把生活中的复杂事情变得简单化,从原来的执行者变成了指挥者,面向对象是基于面向过程发展而来的。
举例:大象装进冰箱
面向过程思考: 打开冰箱 —> 存储大象 —> 关上冰箱
面向对象思考:
冰箱:供电、冰箱门、冷冻、存储
大象:大大的耳朵、短短的腿、会吃会跑又会叫
对于面向过程思想OPP(Procedure Oriented Programming),强调的是过程(动作)主要关注“怎么做”。
对于面向对象思想OOP(Object Oriented Programming),强调的是对象(实体)主要关注“谁来做”。
可见不同的编程思想,思考问题的角度不同!
6.3 类与对象
6.3.1 对象的特征
1.属性——对象具有的各种特征(静态特征),不变的
2.方法——对象执行的操作(动态特征),变的
对象:用来描述客观事物的一个实体,由一组属性和方法构成
6.3.2 类与对象的关系
类:具有相同特征的一组事物通常为一类,是存在于人脑中的一种抽象定义。
对象:对象是类的具体化,即是该类事物实实在在存在的个体。
对比图:
示例:
package sc505_4_0926;
//鸟类
public class Bird {
/*类的成员-变量:(作用范围以及特征)
* 实例变量/成员变量(全局变量)----使用对象来调用
* 静态变量(使用static修饰的)----使用类名调用
* 局部变量----定义在方法中的
* 参数(定义为形参,具体调用时为实参)----定义在方法名后面的括号中
* */
//实例变量/成员变量
//属性---静态特征(不变的)
String color;//颜色
int hit;//命中率
int attack;//攻击值
/*
* 静态变量在整个项目中值保存一份,只能覆盖不能修改,
* 一旦修改所有的都会改变。
* 静态方法中只能调用静态的方法或者变量,普通方法中可以调用静态方法
* 静态的值属于类,不属于对象,所以我们调用静态的东西只能使用类名来调用
* */
static String name="小鸟";
//方法---行为(动态的)
//飞行方法
public void fly(){
//局部变量:局部变量只能在当前方法中使用,超出则不行
int i=3;
System.out.println(color+name+"飞起来了!飞了"+i+"米。");
}
//展示方法
public void disPlay(){
//同一个类中的方法调用,直接使用方法名就可以了,但是我们需要注意静态的问题
//fly();
System.out.println(color+name+"的命中率:"+hit+"攻击值为:"+attack);
}
//攻击方法
//参数:只能在当前方法中使用,超出则不行
public void hit(String s){
System.out.println(color+name+s+"打中了野猪大王。。。。。。");
}
}
说明:此时我们只是创建了一个类,但是这个类到底表示哪种类型的小鸟我们并不知道,只是知道这是一个小鸟的类,所以说类通常都是一种抽象的定义。
6.3.3 对象的创建
创建对象的语法:
类名 对象名 = new 类名();
说明:关键字 new 通常称为创建运算符,用于分配对象内存,并将该内存初始化为缺省值。
一旦 new 完成分配和初始化内存,它就将调用构造函数来执行对象初始化。
当创建一个类时,只是创建了一种新的数据类型。对象是类的一个实例。创建类不是创建对象。
示例:
package com.ambow.test;
public class RedBird {
public static void main(String[] args) {
// 创建鸟类对象
// 创建对象需要使用new关键字
// 使用new关键字创建了Bird类的对象redbird
// redbird 表示了鸟类的一个具体的实列
Bird redbird = new Bird();
// 使用类中的属性或者方法时,我们一般使用:对象.属性或者方法
// 使用属性
redbird.color = "红色小鸟";
redbird.hit = 23;
redbird.attack = 55;
// 使用方法
redbird.fly();
redbird.display();
redbird.hit();
}
}
说明:此案例关联上一个案例。此时我们创建了一个对象,使用new关键字创建出了鸟类具体的对象,也就是红色小鸟,里面包含了红色小鸟的具体特征,所以说对象是一个实实在在存在的东西。
6.3.4 对象的内存分配
分析Bird b = new Bird();
1.第一步,声明Bird类型的一个变量b,这个变量没有定义一个对象。
2.第二步,在内存的堆区创建一个Bird类型的实际对象,并把对于该对象的引用赋给变量b。这是通过使用new运算符实现的
画图讲解:
6.4 类的成员
6.4.1 类的定义
类的定义语法:
[修饰符] class 类名 [继承父类][实现接口]{
成员变量;
[构造函数];
成员方法;
}
注意:每个源代码文件只能有一个public类;文件名必须与public类名相同;
示例:
package com.ambow.teat;
public class Demo {
/**
* 1.定义一个类
* [修饰符] class 类名{
*变量: 静态变量(使用static关键字修饰,使用类名来调用),实列变量(必须使用对象来调用),
* 局部变量(定义在方法中),
* 参数(定义在方法中后面的小括号里面,一半在定义时为形参,调用后传入的值为实参)
[构造方法(函数)]
方法:8种方法 }
* */
//实列变量
String color;
int hit;
int attack;
// 展示方法
public void display() {
System.out.println(color + "命中率为:" + hit + ",攻击值为:" + attack);
}
public void aa(){
System.out.println(color+hit+attack);
}
/**
* 2.构造函数/方法
* 语法格式:
* 1.构造方法名与类名相同
* 2.构造函数没有返回值类型
* 修饰符 构造方法名([形参列表]){
* [初始值]
*
* 如果不手动添加一个构造器的话,系统默认为我们自动提供一个无参构造器
* 如果一旦手动添加了,那么系统就不在为我们提供无参构造器
* }
* */
//无参构造方法/函数/器
public Demo1(){
//默认值
System.out.println("这是一个无参构造器!!");
}
//有参构造函数
public Demo1(String color,int hit,int attack){
//this代表当前类的对象,如果说能用this.出来的变量就是实列变量,点不出来的变量就是局部变量
this.color=color;
this.hit=hit;
this.attack=attack;
}
public static void main(String[] args) {
//无参构造器
Demo1 dd=new Demo1();
//dd.display();
//有参构造器 通过构造函数进行传值
Demo1 d=new Demo1("蓝色小鸟", 70, 800);
d.display();
d.aa();
}
}
说明:上面案例只是为了表示类的成员组成,具体的类的成员我们在接下来会一一讲解。
6.4.2 类中的变量
类中的变量通常被分为四种:实例变量(可以理解为全局变量,但是注意在Java中没有全局变量这个说法),局部变量(定义在方法中的变量),参数(定义在方法名后面的小括号中),静态变量(使用static修饰的变量)
示例(变量的定义):
package com.anbow.test;
public class Bird {
/**
* 变量:实列变量(理解为全局变量) 局部变量 静态变量 参数(一种特殊的局部变量)
* */
/*
* 1.静态变量(类变量)的格式:[修饰符] static 变量类型 变量名[=变量值]; 使用static修饰的变量我们称之为静态变量2.
* 静态变量在编译器内值存在一份,静态变量属于类,不属于对象3.访问静态变量的方式:类名.静态变量名
*/
static String name = "小鸟";// 猴子
/*
* 2.实列变量:color,attack,hit都属于实列变量,每个实列/对象可能有不同的实列变量属性值
* 所以说实列变量的值是根据具体的实列/对象决定的 实列变量需要使用对象/实列来调用或者赋值
*/
String color;// 小鸟的颜色
int hit;// 小鸟的命中率
int attack;// 小鸟的攻击值
// 飞行方法
/*
* 3.参数:参数是定义在方法名后面的小括号里面,其实参数就是一种特殊的局部变量 只能够在本方法中使用,不能在本方法以外的其他任何地方使用
* 在方法定义的参数实际上是形参(没有具体的值),调用方法时我们给他传的值我们称之为实参(具体的值)
*/
public void fly(int m) {
//报错:局部变量只能在它所定义的方法中起作用,不能在其他任何地方被访问到
//System.out.println(str);
System.out.println(color + name + "能飞" + m + "米。");
}
// 展示方法
public void display() {
System.out.println(color + name + "命中率为:" + hit + ",攻击值为:" + attack);
}
// 攻击方法
/*
* 4.局部变量:是根据它所定义的位置来决定了他的作用范围,也就是说定义在方法中的变量,我们把他成为局部变量
* 局部变量只能在它所定义的方法中起作用,不能在其他任何地方被访问到
* */
public void hit() {
String str="用尽吃奶的力";
System.out.println(color + name +str+ "打中了野猪大王!!!!");
}
}
示例(变量的使用):
package com.ambow.test;
public class BirdTest {
public static void main(String[] args) {
//静态变量,静态方法的使用方式:类名.属性或者方法名
System.out.println(Bird.name);
//实列化Bird类,创建Bird类的对象bb
Bird bb=new Bird();
bb.name="猴子";
System.out.println(bb.name);
//实列化Bird类,创建Bird类的对象bule
Bird bule=new Bird();
System.out.println(bule.name);
System.out.println(Bird.name);
bule.color="红色";
bule.fly(23);
//当返回值类型为无返回值时,我们不需要使用变量去承接它,如果是其他数据类型的方法或者变量我们就需要使用
//对应的数据类型去承接它
bule.hit();
}
}
说明:第一次我们调用Bird.name给我们输出的结果为小鸟,当我们重新给它赋值以后在使用这个变量就会变成你后面重新给它赋的值,也就是猴子;因为此时name变量为静态变量,在编译器中只存在一份。因此第二次以后只要调用name变量值都为猴子。
6.4.3 类中的方法
类中的方法通常分为两大类,一种为无参方法,另一种为有参方法。
1.无参方法
无参方法顾名思义就是没有参数的方法,这里我们介绍四种无参方法。
示例(方法的定义):
package com.ambow.test;
public class MethodDemo {
// 方法:1.无参方法
//2.有参方法
/*
* 无参方法的格式:
* [修饰符] 方法返回值类型 方法名(){
* 方法体(方法的具体作用)
* }
*
1.无参无返回值的实列方法
* public:访问修饰
* void:无返回值类型(调用这个方法不需要承接)
* myMethod:方法名
* */
public void myMethod(){
// return;
System.out.println("这是一个无参无返回值的实列方法");
}
/**
* 2.无参有返回值类型的实列方法
* 需要对象来调用,而且需要一个变量来承接这个方法的返回值
* 方法的返回值返回的是一个处理结果,返回的是一个int类型的,返回值的类型一方法返回值的类型必须一致
*
* return的作用:1.如果只使用return时,直接退出此方法
* 2.使用return+返回值结果的方式时,它是返回给方法调用者一个值
* */
//int返回值类型
public int myMethod1(){
System.out.println("这是一个无参有返回值类型的实列方法");
int i=100;
i*=100;
i+=100;
i/=100;
return i;
}
//String返回值类型
public String myMethod2(){
String str="这是一个无参有返回值类型的实列方法2";
return str;
}
//Bird类返回值的类型
public Bird myMethod3(){
String a=myMethod2();
System.out.println(a);
//实列方法中可以使用静态方法
//myMethod4();
//创建bird类的对象
Bird b=new Bird();
b.color="黑色";
b.hit=30;
b.attack=500;
//System.out.println(b);
return b;
}
/**
* 3.无参无返回值的静态方法,也叫类方法;静态方法指的是使用static关键字修饰的方法
* 静态方法与实列方法的区别在于,看方法中有没有static关键字
* 调用静态方法的格式: 类名.静态方法名(); [当然使用对象也是可以的,只是这种方式不常用]
* */
public static void myMethod4(){
System.out.println("无参无返回值的静态方法,也叫类方法;静态方法指的是使用static关键字修饰的方法");
//静态方法中不能调用实列方法或者实列变量,只能调用静态方法或者静态变量
//myMethod3();
}
/**
* 4.无参有返回值的静态方法
* 返回的是一个boolean类型的处理结果
* 调用此方法时,需要用一个与返回值类型一致的变量来承接它
* */
public static boolean myMethod5(){
boolean flag=7>9;
return flag;
}
}
说明:案例中的静态方法与第五章中的初始方法一致。
示例(方法的调用):
package com.ambow.test;
public class Method {
public static void main(String[] args) {
//创建MethodDemo对象mm
MethodDemo mm=new MethodDemo();
//对象调用方法
mm.myMethod();
//这里我们需要使用一个变量来承接它,因为当我们调用这个方法时,此方法会有一个返回值
int i=mm.myMethod1();//i=101
int a=i+10;
System.out.println(a);
// String s=mm.myMethod2();
// System.out.println(s);
Bird bb=mm.myMethod3();
//System.out.println(bb);
bb.display();
//静态调用使用 类名.方法名(如果有返回值,使用相应的类型去承接)
MethodDemo.myMethod4();
boolean t=MethodDemo.myMethod5();
System.out.println(t);
}
}
说明:当方法中有返回值时需要使用return关键字来返回方法的结果,当调用此方法时我们会得到一个可以进行使用的变量,就比如上面的示例中我们在调用有返回值的方法时,我们使用了一个变量来承接它,当然这个变量的类型必须合返回值的类型一致,否则会出现编译错误。
说白了就是将方法的返回值结果赋值给了这个变量,相当于int i=12;只不过现在不是直接赋值的12,而是从方法的返回值而来。当然得到这个结果我们可以继续使用。
2.有参方法
有参方法顾名思义就是有参数的方法,这里我们介绍四种有参方法。
示例(有参方法的定义):
package com.ambow.test;
public class MedthDemo {
/*
* 有参方法的格式:
* [修饰符] 返回值类型 方法名(形参列表){
* 方法体;
* }
* */
/**
* 1.有参无返回值的实列方法,需要使用对象/实列来调用
* num:表示班级人数
* flag:表示标志位
* name:表示姓名
* height:表示身高
* */
public void myMethed0(int num,boolean flag,String name,double height){
if(flag){
System.out.println(name+"说,我们班一共有"+num+"人,最高的为:"+height+"cm");
}else{
System.out.println(name+"说,我们班一共有"+num+"人,最矮的为:"+height+"cm");
}
}
/**
* 2.有参有返回值的实列方法,需要使用对象/实列来调用。调用时需要一个与返回值类型相同类型的变量来承接它
* name:表示姓名
* age:表示年龄
* */
public String myMethed1(String name,int age){
String s=name+"说,我今年"+age+"岁!";
return s;
}
//此方法的返回值为对象类型,也就是我们所说的引用数据类型
public Bird myMethed2(String color,int hit,int attack){
Bird b=new Bird();
b.color=color;
b.hit=hit;
b.attack=attack;
return b;
}
/**
* 3.有参无返回值的静态方法,调用静态方法直接使用类型来调用
* id:表示账号
* pwd:表示密码
* */
public static void myMethed3(String id,String pwd){
System.out.println("我的游戏账号为:"+id+"密码为:"+pwd);
}
/**
* 4.有参有返回值的静态方法,调用静态方法直接使用类型来调用
*
* */
public static int myMethed4(int i){
i*=100;//i=i*100
return i;
}
}
示例(有参方法的调用):
package com.ambow.test;
public class DemoTest {
public static void main(String[] args) {
//调用实列方法需要创建对象,使用对象来调用实列方法
MedthDemo mm=new MedthDemo();
//使用对象来调用实列方法,根据形参的类型和个数对其进行赋值
mm.myMethed0(35, false, "李想", 200);
//使用对象来调用有参有返回值的实列方法,调用时需要一个与返回值类型相同类型的变量来承接它
//快捷键:进入某一个方法或者属性的快捷键: Ctrl+鼠标左键
//返回进入时的界面的快捷键(相当于后退):Alt+方向键的左键
String str=mm.myMethed1("骆佳", 18);
System.out.println(str);
Bird red=mm.myMethed2("紫色", 60, 300);
red.display();
//调用静态方法需要使用类型直接调用
MedthDemo.myMethed3("qwert123", "qwe123");
int i=MedthDemo.myMethed4(20);
System.out.println(i);
}
}
说明:此案例中有一个引用数据类型的使用,我们在此使用的是Bird类型的返回值,
有的人会有疑问,为什么使用Bird类型承接完了以后,可以直接调用Bird类中的方法呢?我们回到此方法中寻找答案,在方法中其实我们已经创建了Bird类的对象,也就是new了Bird类,也给Bird类中的属性赋值,但是在方法中我们没有给具体的值,而是把形参的值给了它,这样有一个好处,也就是我们在调用此方法时,给它什么样的实参,那么它就对应的是什么类型的小鸟。而我们得到的返回值是创建好的对象,也就是说方法的返回值结果本身就是一个已经创建好的对象,所以我们在承接完以后可以直接调用bird类中的方法。