我们在编程中多次提到对象,而编程的目的就是实现模拟现实的方法设计和开发程序,这就是面向对象。
“面向对象”是一个抽象的概念,难点就在于如何从现实中抽出“类”。类就是对某一类的概念上的描述,需要注意的是类并不是具体的事物,类的对象才是现实的、具体的事物。
所以,对象与类交互的过程就是计算机与人的交流。
构造函数和方法重载的用法与c#并无区别:
构造函数语法:
访问修饰符 类名(){
//内容
}
1、类似方法,只是少了一个返回值。
2、方法名有要求:跟类名一致。
3、构造函数也是会被重载。
方法重载定义:
1、在同一个类中。
2、相同的方法名。
3、不同的参数:
1、个数不相同。
2、对应的参数下标的参数类型不同。
示例:
public class Penguin {
String name = "无名氏";
int health = 100;
int love = 0;
String sex = "Q仔";
public Penguin() {
name = "楠楠";
love = 20;
sex = "Q妹";
System.out.println("执行构造方法");
}
public Penguin(String name, String sex) {
this.name = name;
this.sex = sex;
}
public Penguin(String name,int health,int love, String sex) {
this.name = name;
this.health = health;
this.love = love;
this.sex = sex;
}
public void print() {
System.out.println("宠物的自白:\n我的名字叫" + this.name + ",健康值是" + this.health + ",和主人的亲密度是" + this.love + ",性别是" + this.sex + "。");
}
public static void main(String[] args) {
Penguin pgn = null;
pgn = new Penguin();
pgn.print();
pgn = new Penguin("亚亚","企鹅");
pgn.print();
pgn = new Penguin("美美",80,20,"Q仔");
pgn.print();
}
}
定义:继承是描述2个类之间的关系。
c#与java的继承是有所不同的。
java继承语法:
语法:
修饰符 class 子类名 extends 父类名{
//内容
}
从语法可以看到继承的关键字是“extends”与c#的“:”是完全不同的。
示例:
//父类
public class Pet {
private String name = "无名氏";
private int health = 100;
private int love = 0;
public Pet() {
this.health = 95;
System.out.println("执行宠物的无参构造方法");
}
public Pet(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public int getLove() {
return love;
}
public void print() {
System.out.print("宠物的自白:\n我的名字叫" + this.name + ",我的健康值是" + this.health + ",我和主人的亲密度是" + this.love + "。");
}
}
//子类
public class Penguin extends Pet{
private String sex;
public Penguin(String name,String sex) {
super(name);
this.sex = sex;
}
public String getSex() {
return sex;
}
public void print() {
super.print();
System.out.println("性别是" + this.sex + "。");
}
}
//测试类
public class Test {
public static void main(String[] args) {
Penguin pgn = new Penguin("楠楠", "Q妹");
pgn.print();
}
}
定义:一个事务的多种形态。
实现方式:重载和重写。
从以上代码中可以看到,重写时与c#不同的是不用加上“override”关键字来标识的,当然前提是两个类必须有继承关系。
另外重写还需注意:
和c#一样java也有抽象类和抽象方法。
语法:
public abstract class 父类名{
public abstract void 方法名();
}
抽象类与c#相比没有什么区别,只是也不用上“override”关键字来标识。
示例:
//父类,宠物类
public abstract class Pet {
protected String name = "无名氏";
protected int health = 100;
protected int love = 0;
public Pet() {
this.health = 95;
System.out.println("执行宠物的无参构造方法");
}
public Pet(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public int getLove() {
return love;
}
public void print() {
System.out.print("宠物的自白:\n我的名字叫" + this.name + ",我的健康值是" + this.health + ",我和主人的亲密度是" + this.love + "。");
}
public abstract void eat();
}
//子类,企鹅类
public class Penguin extends Pet{
private String sex;
public Penguin(String name,String sex) {
super(name);
this.sex = sex;
}
public String getSex() {
return sex;
}
public void print() {
super.print();
System.out.println("性别是" + this.sex + "");
}
public void eat() {
super.health = super.health + 5;
System.out.println("企鹅" + super.name + "吃饱了!健康值增加5。");
}
public void swimming() {
System.out.println("企鹅" + super.name + "正在游泳。");
super.health = super.health - 10;
super.love = super.love + 5;
}
}
//子类,狗狗类
public class Dog extends Pet {
private String strain;
public Dog(String name,String strain) {
super(name);
this.strain = strain;
}
public String getStrain() {
return strain;
}
public void print() {
super.print();
System.out.println("我是一只" + this.strain + "");
}
public void eat() {
super.health = super.health + 3;
System.out.println("狗狗" + super.name + "吃饱了!健康值增加3.");
}
public void catchingFlyDisc() {
System.out.println("狗狗" + super.name + "制作接飞盘.");
super.health = super.health - 10;
super.love = super.love + 5;
}
}
//主人类
public class Master {
private String name = "";
private int money = 0;
public Master() {}
public Master(String name,int money) {
this.name = name;
this.money = money;
}
public void feed(Pet pet) {
pet.eat();
}
public void feed(Dog dog) {
dog.eat();
}
public void feed(Penguin pgn) {
pgn.eat();
}
public Pet getPet(int typeId) {
Pet pet = null;
if (typeId == 1) {
pet = new Dog("欧欧", "雪纳瑞");
} else if (typeId == 2) {
pet = new Penguin("楠楠", "Q妹");
}
return pet;
}
public void play(Pet pet) {
if (pet instanceof Dog) {
Dog dog = (Dog)pet;
dog.catchingFlyDisc();
} else if (pet instanceof Penguin) {
Penguin pgn = (Penguin)pet;
pgn.swimming();
}
}
}
//测试类
public class Test {
public static void main(String[] args) {
Master master = new Master("王先生",100);
Scanner input = new Scanner(System.in);
System.out.println("欢迎来到宠物店!");
System.out.print("请输入要领养宠物的类型:(1、狗狗 2、企鹅)");
int typeId = input.nextInt();
Pet pet = master.getPet(typeId);
if (pet != null) {
System.out.println("领养成功!");
master.feed(pet);
master.play(pet);
} else {
System.out.println("对不起,没有此类型的宠物,领养失败!");
}
}
}
抽象方法的应用在于必须让子类拥有的动作(方法),也可以说让事物更加具体、丰满。
接口在现实中广泛存在,我们最熟悉的就是“USB接口”了。在这里我带大家回顾一下历史,在个人计算机成为流行的时候,我们需要在电脑上装软件是需要用软盘的,过了一段时间光盘和移动硬盘流行了起来,到现在大多数人使用的就只剩下移动硬盘或者说是U盘了。
那接口在其中有什么作用呢?
接口是联通两个事物的桥梁,你如果需要即可相连,当然不需要的时候直接断开就行,或者更换。代码中的接口也是起到这个作用的,它让我们的代码不需要在每一种情况下定义不同的类,大大的提高了代码的复用率。
语法:
修饰符 interface 接口名 {
//接口成员
}
特点:
不能被实例化(因为本身就是抽象类);
成员方法:只能是抽象方法,访问修饰abstract;
默认访问修饰:public abstract;
成员变量:只能定义静态常量;
默认访问符:public static final;
不能有构造函数
作用:约束子类必须拥有某种行为(方法)。
实现语法:
public class 类名 extends 父类名 implements 接口名1, 接口名2... {
//接口方法
}
修饰符 interface 接口名 extends 父接口1,父接口2... {
//接口成员
}
从语法中不难发现,接口是可以在类或接口中有多个的。
示例:
//父类,门类
public abstract class Door {
public abstract void open();
public abstract void close();
}
//接口类,锁门和开门类
public interface Lock {
void lockUp();
void openLock();
}
//子类,防盗门类
public class TheftDoor extends Door implements Lock {
public void lockUp() {
System.out.println("插进钥匙,向左旋转钥匙三圈,锁上了,拔出钥匙。");
}
public void openLock() {
System.out.println("插进钥匙,向右旋转钥匙三圈,锁打开了,拔出钥匙。");
}
public void open() {
System.out.println("用力推,门打开了。");
}
public void close() {
System.out.println("轻轻拉门,门关上了。");
}
}
//测试类
public class DoorTest {
public static void main(String[] args) {
TheftDoor tfd = new TheftDoor();
tfd.close();
tfd.lockUp();
tfd.openLock();
tfd.open();
}
}
在运行了以上代码后可以看到模拟了一个防盗门的功能,并且按照现实来说,并不是每一扇门都有上锁的功能。接口的意义就在这里,也可以说接口让每一个对象都是独特的。
实现语法:
public class 类名 : 父类, 接口1,接口2... {
//接口方法
}
修饰符 interface 接口名 : 父接口1,父接口2... {
//接口成员
}
c#中的接口实现java相比:
有兴趣可以试着把“门”这个示例在c#中重新编写一遍。
在java的学习中有了较好的基础后,在运用基继承和接口时就能明显的感受到它们给我们带来的好处。结合实际中的例子就可以更好地理解为什么需要这样做,这样就能真正看懂代码,以及如何在生活中运用它。