小谈一下面向对象的3大特征:封装、继承、多态

Java是纯面向对象的编程语言,面向对象的思想其实很简单,就是”anything is Object”,即“万事万物皆为对象”。面向对象最重要的一点,就是要知道面向对象的思想符合人们客观看待世界的规律,是正常而客观的。

面向对象技术主要有以下特点:

1)对象是人们对现实世界中具有某些相同特性的事物的抽象;

2)对象中包含了一定的属性和方法;

3)对象的属性用来表示其具有的相同信息;

4)对象之间的作用可以通过接口完成。

从而总结出面向对象思想的有点:

*单个对象功能专一、简单,而多个对象各司其职、各尽其能,可以健壮地完成软件的要求;

*弱耦合性,对象的耦合性是对象与对象之间、对象与系统之间的联系。对象的耦合性要尽可能的弱;

*可重用性,对象的功能越简单,耦合性越弱,可可重用性就越好;

*可扩展性,当系统中加入新的对象或替换原来的对象时,系统仍然可以保持稳定。

封装:是构建其他代码的基础,没有封装,程序代码就无从谈起,也许是由于翻译的问题,好多人都对封装这个概念很模糊,其实封装就相当于包装,是最常见的。在面向对象的软件中,封装比比皆是。

包结构式一个封装,封装了若干个类;定义的类也是封装,封装了属性和方法;定义的方法也是一个封装,封装了此方法的所有操作,对外部提供公开的接口。所以说,封装在面向对象的软件开发中随处可见。

类的封装时学习的重点,要对类进行规范的封装,有两个层次要注意:

1)对于类的封装,要根据系统的实际需求来决定属性和方法是应该公开还是应该私有,一切从实际出发,不要盲目地全盘私有。

2)对于一般的模式,特别是对应现实中某样东西的数据原型类,属性应该私有。读取和更改对象的属性可以调用公开的访问方法,如getXxx()和setXxx()方法,这些方法可以对参数的数值进行安全检查。

下面看一个封装的小例子吧,代码如下:

package blog;
public class Person {
private String name;
private int age;
private boolean gender;
private Person partner;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age, boolean gender, Person partner) {
super();
this.name = name;
this.age = age;
this.gender = gender;
this.partner = partner;
}
public boolean isOverAgeForMarry(){
if(this.gender && this.getAge()>=23){
return true;
}if(!this.gender && this.getAge()>=21){
return true;
}
return false;
}
public boolean marry(Person p){
if(this.gender == p.gender){
System.out.println("根据国家法律,暂时不允许同性结婚!");
return false;
}if(this.partner != null || p.partner != null){
System.out.println("一方已结婚,再结婚构成重婚罪");
return false;
}if(!this.isOverAgeForMarry() || !p.isOverAgeForMarry()){
System.out.println("未到结婚年龄!");
return false;
}
System.out.println("恭喜!"+this.name+"和"+p.name+"结婚成功");
this.partner = p;
p = this.partner;
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isGender() {
return gender;
}
public void setGender(boolean gender) {
this.gender = gender;
}
public Person getPartner() {
return partner;
}
public void setPartner(Person partner) {
this.partner = partner;
}
}

    测试程序如下:

package blog;
public class MarryTest {
public static void main(String[] args) {
Person p5 = new Person("许仙",24,true,null);
Person p6 = new Person("白素贞",23,false,null);
Person p7 = new Person("小青",18,false,null);
System.out.println("小青和许仙申请结婚,得到答案是:");
p5.marry(p6);
System.out.println("白素贞和许仙申请结婚,得到答案是:");
p5.marry(p6);
p7.setAge(25);
System.out.println("小青现在已经"+p7.getAge()+"岁了,申请和许仙结婚,得到答案是:");
p7.marry(p5);
p5.setPartner(null);
System.out.println("许仙离婚了,成了自由人,申请和小青结婚,得到答案:");
p5.marry(p6);
}
}

    输出结果如下:

小青和许仙申请结婚,得到答案是:
恭喜!许仙和白素贞结婚成功
白素贞和许仙申请结婚,得到答案是:
一方已结婚,再结婚构成重婚罪
小青现在已经25岁了,申请和许仙结婚,得到答案是:
一方已结婚,再结婚构成重婚罪
许仙离婚了,成了自由人,申请和小青结婚,得到答案:
恭喜!许仙和白素贞结婚成功

继承:在软件的编码过程中,继承是面向对象的若干种关系的基础。正是因为有了继承,才让面向对象的程序设计变得更加精妙。同时继承的功能也不仅仅是代码复用,更是多态的基础。

有下述3个定理决定了当java类型在继承是,生成子类时的步骤。

1)任何子类的构造方法一定会调用父类的构造方法;

2)任何类斗都有构造方法;

3)任何子类构造方法的第一行,一定是super()或者是this()这样的调用。

关于super和this的用法:

this:指本类对象

super:指父类对象

1)可以通过super.来访问父类的属性或方法,属性注意修饰符的作用范围;

2)子类中可以通过super.访问父类的构造方法,给属性赋值;

3)如果子类构造中没有对本类及父类的构造方法的调用,默认有super();

    如果一个类没有指定继承其他父类,则它的父类是Object,对于一个对象来说,如果直接用syso输出该对象,是输出该对象的字符串形式,相当于默认调用对象.tosSring()

由于Object的toString()对我们没有意义,所以我们需要对String()方法进行重写,重写是注意重写规则。

多态:多态顾名思义,就是一个对象,多种形态,多态可以有多种理解,一种是方法的多态,即方法的覆盖和重载,这种多态提的比较少,一般讲的多态是指对象的多态:

    *当把子类对象当做父类对象来看时,就只能调用父类中原有定义的属性和方法。子类自己扩展的属性和方法就不能调用了。

    *当把子类对象当做父类对象看是,如果子类重写了父类中的方法,则调用该方法时调用的是子类重写后的方法。

    下面一个例子解释一下上述的问题:

package blog;
public class Pet {
private String name;
private int age;
private String color;
private double weight;
public Pet() {
super();
// TODO Auto-generated constructor stub
}
public Pet(String name, int age, String color, double weight) {
super();
this.name = name;
this.age = age;
this.color = color;
this.weight = weight;
}
@Override
public String toString() {
return "Pet [name=" + name + ", age=" + age + ", color=" + color
+ ", weight=" + weight + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public void eat(String food){
System.out.println(name+"喜欢吃"+food);
}
public void eat(int i){
System.out.println(name+"每天吃"+i+"顿饭");
}
public void speak(){
System.out.println("MyPet likes Speaking!");
}
}

    子类继承父类代码如下:

package blog;
public class MyDog extends Pet {
public MyDog(String name,int age,String color,double weight) {
super(name,age,color,weight);
}
public void speak(){
System.out.println(this.getName()+"说:旺旺,我是一只可爱的小狗狗!");
}
public void watchHome(){
System.out.println(this.getName()+"还会看家哦!");
}
}

    测试方法:

package blog;
public class TestMyDog {
public static void main(String[] args) {
Pet mydog = new MyDog("七仔",5,"灰色",0.25);
if(mydog instanceof Pet){
mydog.eat("meat");//mydog可以调用Pet方法
mydog.speak();//mydog可以调用重写过的Pet方法
}
//      mydog。watchHome();//mydog不可以调用子类(自己)独有的方法,需要强转如下:
((MyDog)mydog).watchHome();
}
}

    输出结果如下:

七仔喜欢吃meat
七仔说:旺旺,我是一只可爱的小狗狗!
七仔还会看家哦!

    其实封装继承多态是十分强大的,由于现在学的有限,希望以后会写出好的代码~^_^~