首先怎么理解面向过程:举个例子,拿买笔记本电脑而言,最新的配置,各品牌有没有新上市的电脑,各品牌中的各个型号哪个性价比高,哪一种类型比较适合我们,搞清楚之后,我们得去商城,看电商,哪里的价格合适。从准备买到买到手,所有的事情都一手解决,这我们就可以理解为是 面向过程。一系列过程对于不懂电脑的人而言,可能查半天也弄不清楚。这时就需要寻求帮助,找一个懂电脑的朋友,告诉他你对电脑的需求,上述的问题他可以很快的解决并向你推荐出适合你的电脑,并且可以让他帮你找一个合适的渠道购买。这个朋友对你而言便是面向对象,过程便可以由这个对象去解决。
面向对象是基于面向过程的编程思想 特点:
是一种更符合我们思想习惯的思想可以将复杂的事情简单化将我们从执行者变成指挥者面向对象开发,就是不断的创建对象,使用对象,指挥对象做事情 面向对象设计,其实就是在管理和维护对象之间的关系 面向对象特征,封装,继承,多态 面向过程和面向对象都是人类的常用思考方式。 是不是互斥的? 不是 是不是相互依赖的? 不是 没有纯粹的面向对象 但是有纯粹的面向过程 面向对象的思想其实是基于面向过程
需求:把大象装冰箱里 对象:大象、冰箱 分三步:
打开冰箱门将大象装进去关闭冰箱门分析发现打开、装、关闭都是冰箱的功能。 即冰箱对象具备如下功能: 冰箱打开 冰箱存储 冰箱关闭 用伪代码描述,上述需求中有两个具体的事物 : 大象 和 冰箱
描述大象: 大象 { } 描述冰箱 冰箱 { 打开(){ //打开的方法 } 存储(大象){ //将大象传进去,储存 } 关闭(){ //关闭的方法 } }当把具体的事物描述清楚之后,需要使用这些具体的事物,Java使用具体的事物,需要通过new关键 字来创建这个事物的具体实例 使用对象
创建冰箱的对象冰箱 bx = new 冰箱();
调用冰箱的功能 对象.功能();bx.打开(); bx.存储(new 大象()); bx.关闭()
总结: 3. 先按照名词提炼问题领域中的对象 4. 对对象进行描述,其实就是在明确对象中应该具备的属性和功能 5. 通过new的方法就可以创建该事物的具体对象 6. 通过该对象调用它以后的功能
学习编程语言的目的,就是为了模拟世界的事物,实现信息化。 如何表示一个现实世界的事物:
属性:就是该事务的描述信息(成员变量)行为:就是该事务能够做什么(成员函数)类:是一系列具有相关属性和行为的事物的集合,是一个抽象的概念 对象:是该类事物的具体表现形式,具体存在的个体
定义类其实就是定义类的成员(成员变量,成员函数)
类是对象的模板。它定义对象的属性,并提供用于创建对象的构造方法以及操作对象的普通方法。类也是一种数据类型。可以用它声明对象引用变量。对象引用变量中似乎存放了一个对象,但事实上,它包含的只是对该对象的引用。严格地讲,对象引用变量和对象是不同地,但是大多数情况下,它们地区别是可以忽略地。构造方法在使用new操作符创建对象的时候被调用 构造方法是一种特殊的的方法。它有以下三个特殊性:
构造方法必须具备和所在类相同的名字。构造方法没有返回值,甚至连void也没有。构造方法是在创建一个对象使用new操作符时调用。构造方法的作用是初始化对象。和所有其他方法一样,构造方法也可以重载(也就是说,可以有多个同名的构造方法,但它们要有不同的签名),这样更易于用不同的初始数据值来构造对象。 通常,在不需要写构造方法的情况下,类会提供一个隐藏的无参的默认构造方法,当且仅当类中没有明确定义任何构造方法时才会自动提供它。
class refrigerator{ //冰箱的类 pritave double temperature; //冰箱的属性,温度 refrigerator(){ //无参的构造方法 } refrigerator(double temperature){ //有参的构造方法,可以在创建对象的时候对冰箱的温度赋值 } }创建对象的时候可以对对象进行初始化? 可以 构造函数能否重载? 可以 构造函数有没有返回值? 没有 但是有return 构造函数能否调用其他构造函数? 可以 this(…) 必须在第一行 构造函数之间能够相互调用? 不能 是递归调用,会不停的进栈 构造函数能够调用成员函数? 可以,无非是构造函数中某段代码的封装不应该作为对象的特有行为 需要private 成员函数能否调用构造函数? 不能 既然有了构造函数 还需要setget不?不一定,看具体业务需求
在类中的位置不同
成员变量 类的里面,方法的外面局部变量 声明和使用都在方法的内部在内存中的位置不同
成员变量 堆内存中对象的所属空里间局部变量 栈内存中函数的所属空间里生命周期不同
成员变量 随着对象的创建而存在,随着对象的消失而消失局部变量 随着方法的进栈而存在,随着方法的弹栈而消亡初始化值不同
成员变量 在堆内存中有 默认初始化 > 显示初始化 > 针对性初始化局部变量 没有默认的初始化值 必须先定义在赋值后才能使用调用范围 成员变量 基本全局(不能被静态函数直接调用) 局部变量 在函数中其所属最近的 { } 内
注意: 为避免混淆和错误,除了方法中的参数,不要将实例变量或静态变量的名字作为局部变量名。
注意:
引用类型数据域的默认值是 null数值类型数据域的默认值是 0boolean 类型数据域的默认值是 falsechar类型数据域的默认值是 ’\u0000‘但是,Java 没有给方法中的局部变置赋默认值匿名对象:就是没有名字的对象,是对象的一种简化表示形式
匿名对象的两种使用情况:
对象调用方法仅仅一次的时候作为实际参数传递封装概述:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。 好处:
隐藏实现细节,提供公共的访问方式提高代码的复用性提高安全性封装原则:
将不需要对外提供的内容都隐藏起来把属性隐藏,提供公共方法对其访问private关键字是一个权限修饰符,可以修饰成员,被修饰的成员只在本类中才能访问。防止外界直接修改值。 在定义私有数据域的类外的对象是不能访问这个数据域的。 private最常见的应用:
把成员变量用private修饰提供对应的get(访问器)和set(修改器),二者根据需求决定是否需要存在 class Demo03{ public static void main(String[] args){ Person p1=new Person(); p1.setAge(25); //通过set接间传值 p1.getAge(); //通过get接间访问 } } class Person{ private int age; private String name; Person(){ this(0,null);//this(...) 调用当前类的其他构造函数 必须在第一句 print(); } //通过set方法,避免直接传值,产生出错误地信息 public void setAge(int age){ //局部变量age 成员变量age if(age<0){ this.age=0; }else{ this.age=age; } } public int getAge(){ return this.age; } }注意: 为防止数据被篡改以及使类更易于维护,最好将数据域声明为私有的。
this代表所属类的对象引用,方法被哪个对象调用,this就代表哪个对象。this引用通常是省略掉的。然而,在引用隐藏数据域以及调用一个重载的构造方法的时候,this引用是必须的。
模拟枪战射击, 分为:玩家,枪,弹夹,子弹 ,4个类;再加一个运行程序的主类,共5个类 玩家 名字; 血量值; 枪; 捡枪(枪); 装弹夹(弹夹); 射击(玩家); 掉血(伤害值) 枪 弹夹; 装弹夹(弹夹); 开枪(玩家) 弹夹 子弹[]; 上子弹(子弹); 出子弹() 子弹 伤害值; 击中(玩家)
class Demo{ public static void main(String[] args){ //创建名为老张,老王血量各100的两个玩家 Player p1=new Player("老张",100); Player p2=new Player("老王",100); //老张对老王开枪,没有枪 p1.shoot(p2); //创建枪,给p1(老张) Gun gun=new Gun(); p1.takeGun(gun); //老张对老王开枪,没有弹夹 p1.shoot(p2); //创建弹夹,给枪上弹夹 Clip clip=new Clip(); p1.loadClip(clip); //老张对老王开枪,没有子弹 p1.shoot(p2); System.out.println("========="); //上10颗子弹 for(int i=1;i<=10;i++){ clip.putBullet(new Bullet()); } System.out.println("========="); // //老张对老王连续开枪 for(int i=1;i<=11;i++){ p1.shoot(p2); } } } //玩家 class Player{ //姓名,血量和枪 private String name; private int HP; private Gun gun; //玩家的构造函数,对创建对象的属性赋值 public Player(String name,int HP){ this.name=name; this.HP=HP; this.gun=null; System.out.println("玩家"+this.name+"诞生,血量"+this.HP); } //拿枪 public void takeGun(Gun gun){ //如果没有枪,引用类型默认为null if(this.gun==null){ this.gun=gun; System.out.println("玩家"+name+"拿起了一把枪"); }else{ System.out.println("玩家"+name+"已拿枪"); } } //上弹夹 public void loadClip(Clip clip){ //判断有没有枪 if(this.gun==null){ System.out.println("玩家"+name+"没有枪,装不了弹夹"); }else{ System.out.println("玩家"+name+"给枪装了弹夹"); this.gun.loadClip(clip); } } //开枪 public void shoot(Player enemy){ if(this.gun==null){ System.out.println("玩家"+name+"没有枪,不能向"+enemy.getName()+"开枪"); }else{ System.out.println("玩家"+name+"向玩家"+enemy.getName()+"开了一枪"); //调用的对象向传入的对象开枪 this.gun.fire(enemy); } } //掉血 public void bloodLoss(int damage){ //当前对象的生命值大于子弹的伤害值,掉血;小于,死亡 if(this.HP>damage){ this.HP-=damage; System.out.println("玩家"+name+"收到伤害"+damage+",剩余"+this.HP+"血量"); }else{ System.out.println("玩家"+name+"已死亡"); } } //get方法,获取姓名,不需要改变姓名所以没有set方法 public String getName(){ return this.name; } } //枪 class Gun{ private Clip clip; //弹夹的构造函数 public void loadClip(Clip clip){ this.clip=clip; System.out.println("枪装上了弹夹"); } //开枪的函数, public void fire(Player enemy){ if(clip==null){ System.out.println("枪没有弹夹,放了个空枪"); }else{ //有弹夹,创建子弹的对象,如果子弹不为空,则发射 Bullet bullet=clip.getBullet(); if(bullet!=null){ System.out.println("枪向"+enemy.getName()+"发射了一个子弹"); //向传入对象发射子弹 bullet.hit(enemy); }else{ //没子弹 System.out.println("枪放了个空枪"); } } } } //弹夹 class Clip{ private Bullet[] bullets; private int size; //弹夹的构造方法,创建一个弹夹对象,默认拥有30个子弹空间,size用来表示当前子弹数 public Clip(){ this.bullets=new Bullet[30]; this.size=0; } //发射子弹 public Bullet getBullet(){ if(size==0){ System.out.println("弹夹为空"); return null; }else{ //[1,1,1,1,1,1,1,0,0,0,0,0] //每发射一次,子弹数-1 Bullet bullet=bullets[size-1]; size--; System.out.println("弹夹剩余"+size+"/"+bullets.length); return bullet; } } //上子弹 public void putBullet(Bullet bullet){ if(size==bullets.length){ System.out.println("弹夹已满"); }else{ bullets[size]=bullet; size++; System.out.println("弹夹剩余"+size+"/"+bullets.length); } } } //子弹 class Bullet{ private int damage=30; //子弹击中对方 public void hit(Player enemy){ System.out.println("一个子弹击中了"+enemy.getName()); //调用的对象掉血,掉血血量为子弹伤害值 enemy.bloodLoss(damage); } }