-
类和对象
面向对象的程序设计是当今主流的程序设计范型,这种设计思路取代了之前的结构化、过程化程序设计开发技术。Java就是完全面向对象的。
面向对象的程序是由“对象”组成的。“对象”是指一个具体的事物,例如:你、我、一个叫某某某的大学生、你的手机、英雄联盟中的剑姬和石头人等等。(值得注意的是,对象要足够具体,不能是手机、水杯这样的泛指)
在日常生活中,我们通常将具有相同属性特征、相同行为或者使用方法的“对象”归为一“类”。比如把你、我都归为人类;你的手机、我的手机都归为通讯设备类;剑姬、石头人都归为英雄类。
按照日常生活中的分类理解就没有问题,但是和生产手机产品经理或者创建剑姬这类英雄的设计师的逻辑思路不太一样。我们在生活中是作为消费者、产品的使用者,才会有先拿到手机,再分类的思路,而作为产品经理、设计师等开发者而言,他们先看到通讯设备该有的属性、功能,再从中设计出的手机。
所以我们作为程序的开发者,应该先看到抽象的类,再从中实例化出对象。比如我们设计英雄类的时候,英雄都有血量、攻击力、防御力等属性特征,还有攻击的行为。再设计剑姬和石头人等有不同血量、攻击力、防御力数值的对象。
“ 类( class) 是构造对象的模板或蓝图。我们可以将类想象成制作小甜饼的切割机,将对 象想象为小甜饼。由类构造(construct) 对象的过程称为创建类的实例 (instance )”,引用自《Java核心技术卷》。能够帮助我们更好的理解。
看看在Java中具体怎么实现吧!
//定义英雄类
public class Hero {
//定义英雄的名字、血量、伤害等属性
public String name;
public int blood;
public int damage;
//定义英雄的攻击方法
public void hurt(Hero c) {
//血量=血量-伤害
blood -= c.damage;
//输出语句
System.out.println(c.name + "正在攻击" + name + "," + name + "受到" + c.damage + "伤害,剩余血量" + blood);
}
}
//开始创建具体的对象
public class manage {
public static void main(String[] args) {
//新建剑姬和石头人对象,并设置他们的攻击力血量
Hero jj = new Hero();
Hero str = new Hero();
str.setName("石头人");
str.setBlood(1500);
str.setDamage(50);
jj.setName("剑姬");
jj.setBlood(1200);
jj.setDamage(100);
//还为攻击方式添加了循环,让他们互相攻击直到一方倒下
while (jj.getBlood()>0 && str.getBlood()>0){
jj.hurt(str);
str.hurt(jj);
}
if (jj.getBlood()>0){
System.out.println(jj.getName() + "胜出");
}
else{
System.out.println(str.getName()+ "胜出");
}
}
}
//快动手运行起来试试吧
2、方法和构造方法
方法 存在于类与对象中。1中介绍的人类的行走、吃饭可以是方法,通讯设备的相互通信可以是方法,英雄间的相互攻击可以是方法。
方法的格式:访问修饰符 返回值类型 方法名(参数类型 参数名){方法体}
构造方法 的主要作用是完成对象的初始化工作,并且把定义对象的参数传给对象成员。每个类都有构造方法,但是1中的例子没有构造方法依然能运行,这是因为如果没有写构造方法的时候,类会默认一个无参的构造方法。例如public Hero () { }
关于构造方法还有几点需要注意的是:
构造方法与类同名;
构造方法没有返回值;
构造方法可以有多个参数;
每个类可以有多个构造方法,考构造方法中的参数数量、类型、顺序来区分;
构造方法只有在创建对象的时候起作用。
3、继承
继承(inheritance),是学习面向对象程序设计的另外一个基本概念。
继承 的概念源于生物间的特征延续,生物父母和后代间的继承,后代会继承父母的生物特征,有时又会和父母有些不同。比如人类后代继承父母的人类特征:属性(身体构造)和方法(行为模式),有时会产生新的特征。
将继承的概念引入编程中,被继承类可以称为 超类 或 父类,继承类可以称为子类。子类可以继承 父类 的全部属性和方法。并和生物的继承相同,可以在子类中增加新的属性和方法,也可以重写父类中的公有属性和方法。值得一提的是,不像生物中继承可以从父母双方继承那样,Java语言只支持单继承。
继承的引入,让代码实现了共享,提高了开发的效率。作为开发者,在设计产品时,有相近的功能、或者存在迭代关系的产品时,都希望在前者的基础上设计改进,而不是浪费大量的时间重复之前做过的工作。比如在生产新型号的手机时,可以沿用上一代的配置和功能,即属性和方法,再在其中进行必要的提升和修改,这样工作量会小很多,效率大大提高。
和之前一样,用一段关于英雄联盟游戏中的代码来演示,看看在Java编程中怎么实现继承吧!
//英雄们的属性有名字、攻击力和血量,方法是普通攻击
//英雄又分为战士和坦克两大类:坦克有新的属性:防御力;战士新的方法:普通攻击两次+额外一次攻击
//定义英雄类
public class Hero {
//定义英雄属性 名字 攻击力 血量
private String name;
private int damage;
private int blood;
//子类中必须调用一次父类的构造器,因此定义一个无参构造器,方便调用
public Hero() {
}
//构造方法初始化属性
public Hero(String name,int damage,int blood) {
this.name = name;
this.damage = damage;
this.blood = blood;
}
//因为属性的访问修饰符为private私有类型,想在子类中访问可以使用set、get方法
public void setName(String name) {
this.name = name;
}
public void setDamage(int damage) {
this.damage = damage;
}
public void setBlood(int blood) {
this.blood = blood;
}
public String getName() {
return name;
}
public int getDamage() {
return damage;
}
public int getBlood() {
return blood;
}
//攻击方法
public void hurt(Hero c) {
System.out.println(name + "正在攻击" + c.name + "," + c.name + "受到" + damage + "伤害,剩余血量" + c.blood);
}
}
//创建战士类 继承 英雄类
public class Soldier extends Hero {
private int count = 0;
//属性 名字 攻击力 血量都继承父类,但需要通过get方法调用父类的私有属性
//创建新的方法 攻击
public void hurtOnce(Hero c) {
c.setBlood(c.getBlood()-getDamage());
//System.out.println(getBlood());
super.hurt(c); //使用super. 调用父类方法
}
//重写父类中的攻击方法 先攻击一次,再判断是否需要额外攻击
public void hurt(Hero c) {
this.hurtOnce(c);
if (this.isExtra()) {
this.hurtOnce(c);
System.out.println("额外攻击");
}
}
//判断是否需要额外攻击
public boolean isExtra() {
count++;
count %= 3; // 除余算法
return count==0;
}
}
//同战士类
public class Tank extends Hero {
private int defense;
public void setDefense(int defense) {
this.defense = defense;
}
public void hurt(Tank c) {
c.setBlood(c.getBlood() - (getDamage()- defense));
super.hurt(c);
}
}
//最后和前文中一样,创建各自类的对象,并添加攻击的循环判定就大功告成咯
public class manage {
public static void main(String[] args) {
Soldier jj = new Soldier();
Tank str = new Tank();
str.setName("石头人");
str.setBlood(1500);
str.setDamage(50);
str.setDefense(40);
jj.setName("剑姬");
jj.setBlood(1200);
jj.setDamage(100);
while (jj.getBlood()>0 && str.getBlood()>0){
jj.hurt(str);
str.hurt(jj);
}
if (jj.getBlood()>0){
System.out.println(jj.getName() + "胜出");
}
else{
System.out.println(str.getName()+ "胜出");
}
}
}
代码中提到的访问修饰符还有几种类型:
private------------------>本类可访问,外部类借助set、get方法访问
public------------------->对外部完全可见
protected------------->本包和所有子类可见
无------------------------>本包可见
快动手试试吧
4、接口
待更新~~~