您的位置:华清远见教育科技集团 >> Android资料 >> java面向对象编程  
 
java面向对象编程
分享到:

本文关键字:java面向对象编程,java面向对象程序设计,java类的声明,java属性的声明,java方法的声明,java构造器,android java

1 从结构化程序设计到面向对象程序设计

面向对象程序设计与结构化程序设计都是设计和构造程序的方法。近年来面向对象程序设计的方法越来越受到人们的重视,成为解决软件危机的新途径,而结构化程序设计方法的使用在逐渐减少。几乎每一种新推出的程序开发工具或语言都采用了面向对象程序设计的思路,面向对象程序设计形成了一套与结构化程序设计具有很大差异的方法。

结构化程序设计方法又称面向过程设计方法,起源于20世纪70年代。在这之前的程序设计基本采用过程式程序设计,虽然汇编语言已经取代了机器语言,但是对于一般的程序设计人员而言,它还是太抽象、太隐晦了。如果计算机要得到更大的发展,必须发明一些比汇编语言更易于阅读、编写的程序语言。在这种需求的刺激下,结构化程序设计方式产生了机构化程序设计,主要特点是采用自顶向下、逐步求精的程序设计方法:使用3种基本控制结构构造程序,任何程序都可由顺序、选择、重复3种基本控制结构构造。结构化设计的根本目标就是把复杂的系统分解成简单模块的层次结构。例如,你要装修房子,以前的过程式程序设计要求你必须从客厅开始装修,然后是卧室、厨房、卫生间,顺序不能颠倒,客厅没装好之前,休想踏进你的卧室半步。而结构化程序设计方式将你的客厅、卧室、卫生间、厨房都独立成一个模块,互相之间可以互不干扰地进行。

虽然结构化程序设计解决了软件设计开发中的一部分问题,但是它仍然存在不足。用结构化方法开发的软件,其稳定性、可修改性和可重用性都比较差,这是因为结构化方法的本质是功能分解,从代表目标系统整体功能的单个处理着手,自顶向下不断把复杂的处理分解为子处理,这样一层一层地分解下去,直到仅剩下若干个容易实现的子处理功能为止,然后用相应的工具来描述各个低层的处理。因此,结构化方法是围绕实现处理功能的“过程”来构造系统的。然而,用户需求的变化大部分是针对功能的,因此,这种变化对于基于过程的设计来说是灾难性的。用这种方法设计出来的系统结构常常是不稳定的,用户需求的变化往往造成系统结构的较大变化,从而需要花费很大代价才能实现这种变化。

结构化程序设计的局限性催生了面向对象的思想。面向对象(OO)并不是一个新概念,它在20世纪70年代就出现了,但是,因为受到软/硬件的限制,直到90年代,它才为大众所接受并成为程序设计的主流思想。面向对象的方法与结构化的程序设计根本区别在于把系统看成一起工作来完成某项任务的对象集合,而对象是系统对消息做出响应的事物,所以面向对象方法中值得关注的不是它应该做什么,而是它如何做出反应,也就是消息,这是和结构化设计的根本不同。

在面向对象的设计思想指导下,产生了第一个面向对象的语言——20世纪60年代的Simula-67。它的目的是解决模拟问题。一个典型的应用是模拟银行系统的运作(银行是早采用计算机的行业之一),将银行的出纳部门、客户、业务等实体模拟成一个个的对象,把这些在程序的运行中除了状态外其他方面都一样的对象归纳在一起,就成了更高抽象层面的“类”。在面向对象思想指导下产生了成功的面向对象编程语言——Smalltalk。并且,在此基础上又诞生了应用更加广泛的面向对象编程语言——C++及Java。

2 面向对象特征

1.对象唯一性

每个对象都有自身唯一的标识,通过这种标识,可找到相应的对象。在对象的整个生命期中,它的标识都不改变,不同的对象不能有相同的标识。

2.抽象性

抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。

3.封装性

封装性就是把对象的属性和服务结合成一个独立的单位,并尽可能隐蔽对象的内部细节。

4.继承性

继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。

继承性是面向对象程序设计语言不同于其他语言的重要的特点,是其他语言所没有的。

5.多态性

多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象收到同一消息可以产生不同的结果,这种现象称为多态性。

3 面向对象程序设计

3.1 知识准备:面向对象编程术语

● 类(Class):类是对某种类型的对象定义变量和方法的原形。它表示对现实生活中一类具有相同特征的事物的抽象,是面向对象编程的基础。

● 对象(Object):也称为实例(Instance),是类的具体存在。

● 属性(Attribute):也称为成员变量、实例变量(Instance Variable)、字段(Field),表示一个对象所具有的状态。本书中,通常使用变量或者属性来称呼它。

● 方法(Method):用于表示对象可以执行的动作,它包括名称、参数、返回类型,以及方法体等内容。

● 构造器(Constructor):也称为“构造方法”。用于创建和初始化一个实例的特殊方法,包括名称、参数及“方法体”等,需要注意的是,它的名称必须和类名一致。

● 包(Package):可以使用它来组织编写类,使得类的组织更加有序。

3.2 知识准备:对象

我们每天的生活、工作,无时无刻不在和“对象”打交道——衣服、食物、房子、汽车等。当处理这些对象时,不会将这些对象的属性(对象所具有的特点)和操作分开。如进出“房间”时,不会将“房门”这个属性和“开门”这个操作分开,它们是联系在一起的。

面向对象的编程思想力图使得程序和现实世界中的具体实体完全一致。

人们通过观察对象的属性和行为来了解对象。对象的属性描述了对象的状态,对象的行为描述了对象的功能。对象一般有如下特性:

(1)有一个名字以区别于其他对象。

(2)有一些状态用来描述它的某些特征。

(3)有一组操作,每个操作决定了对象的一种功能或行为。

这样,可以让程序员乃至非专业人员更好地理解程序。它涉及一个从“具体”到“抽象”,再从“抽象”到“具体”的过程。所谓“从‘具体’到‘抽象’”,也就是将现实世界中的一个个具体的“物体”(或称为“实体(Entity)”)相应的特征和行为抽象出来,并且将各种具有相同特征的“物体”分为一个个的“类”,如“汽车”类、“人”类、“房子”类等;而所谓“从‘抽象’到‘具体’”,就是将上面抽象出来的对应物体的“类”,使用具体的计算机语言来描述,比如,使用Java语言来描述“汽车”类、“人”类、“房子”类等,和使用C++语言来描述这些类是有区别的。

正如前面所述,“类”相对于现实世界中的“实体种类”(Entity Category),如汽车、人类、房子等,它是现实生活中某类实体的抽象。而对象,或者实体(Instance),指的是这些种类中的一个个具体存在,如Benz-600、Santana-2000等具体的汽车,或者张三、李四等具体的个人。类和对象是面向对象编程思想中的核心和基础。类是作为对象的蓝图而存在的,所有的对象都依据相应的类来产生,在面向对象的术语中,这个产生对象的过程称为“实例化”。

用一个具体的例子来进一步说明“类”和“对象”之间的联系与区别。以汽车为例,只要是汽车,都应该有以下一些特性:轮子、引擎、方向盘、刹车等组件,可以通过这些组件来操作汽车,改变汽车的状态,如加速、转向、减速等,这些都是汽车的共性。具体到某辆汽车,它可能有80cm的轮子、40cm的方向盘、A6引擎,它是一个确定的实例。使用“汽车类”这个蓝图,就可以生产出一辆辆的汽车“实例”。这和盖房子一样,根据一张图纸,可以盖出任意数量的房子,而这些房子都有一样的特征。

3.3 知识准备:类

如果说一切都可以成为对象,那么是什么决定了某一类对象的外观和行为呢?

类是对某个对象的定义,用来描述一组具有相同特征对象的:

(1)应包括的数据。

(2)行为特征。

类包含有关对象动作方式的信息,包括它的名称、方法、属性和事件。实际上类本身并不是对象,因为它不存在于内存中。当引用类的代码运行时,类的一个新的实例,即对象,就在内存中创建了。一个类能从这个类在内存中创建多个相同类型的对象。因此,类应该包括两个方面的内容。

(1)属性:用来描述对象的数据元素称为对象的属性(也称为数据/状态)。

(2)方法:对对象的属性进行的操作称为对象的方法(也称为行为/操作)。

3.4 知识准备:类的声明

Java语言中类的声明,也称类的定义,其语法规则如下:

[< modifiers>] class < class_name> {
        [<attribute_declarations>]
        [<constructor_declarations>]
        [<method_declarations>]
    }

其中各组成部分的含义如下:

<modifiers>为修饰符,可用的有public、abstract和final等关键字(关键字是Java语言中赋以特定含义,并用做专门用途的单词,类名、方法名和属性名及变量名不能是关键字),用于说明所定义的类有关方面的特性。对于各种关键字和它们的含义及各自的适用范围,请看后续章节的介绍。

类成员有3种不同的访问权限:

(1)公有( public关键字修饰 )类成员可以在类外访问。

(2)私有( private关键字修饰 )类成员只能被该类的成员函数访问。

(3)保护( protected关键字修饰 )类成员只能被该类的成员函数或派生类的成员函数访问。

class关键字表明这是一个类的定义,将告诉你一个新类型的对象看起来是什么样的。

<class_name>是类的名字,类名一般使用一个用于表示这个类的名词来表示。

<attribute_declarations>是属性(Attribute)声明部分。

<constructor_declarations>是构造器(Constructor)声明部分。

<method_declarations>是方法(Method)声明部分。

可以将上述的“学生”实体的基本特征当成“学生”类的属性,然后,再定义一些方法来对这些属性进行操作。这里,将这些操作属性的方法定义得很简单:每个属性都有相应的设置(setter)和获取(getter)方法,设置方法将传入的参数赋给对象的属性,而获取方法取得对象的属性。

源文件:Student.java

public class Student {
        // 定义属性
        String name;
        String sex;
        int grade;
        int age;

        // 定义属性“name”的设置方法
        public void setName(String _name) {
            name = _name;
        }

        // 定义属性“name”的获取方法
        public String getName() {
            return name;
        }

        // 定义属性“Sex”的设置方法
        public void setSex(String _sex) {
            sex = _sex;
        }

        // 定义属性“Sex”的获取方法
        public String getSex() {
            return sex;
        }

        // 定义属性“grade”的设置方法
        public void setGrade(int _grade) {
            grade = _grade;
        }

        // 定义属性“grade”的获取方法
        public int getGrade() {
            return grade;
        }

        // 定义属性“age”的设置方法
        public void setAge(int _age) {
            age = _age;
        }

        // 定义属性“age”的获取方法
        public int getAge() {
            return age;
        }
    }

3.5 知识准备:属性的声明

类的定义中所包含的数据称为属性,也称为数据成员,比如2.2.4节示例中的Student类中定义了4个属性——name、sex、grade、age。属性声明的语法规则如下:

[< modifiers>] <data_type> < attr_name>;

其中:

● < modifiers>为修饰符,可用的有public、private、protected、final、static等,用于说明该属性的一些性质。

● <data_type>是该属性的数据类型,属性可以是Java基本类型的一种,如下面的示例中MyClass类中声明的属性classID等,也可以是任何类型的对象,可以通过引用它进行通信。例如MyClass类中声明的属性myTeacher。

● <attr_name>是属性名称,属性名称的首字母一般采用小写方式。

MyClass.java
    public class MyClass {
        int classID;
        String className;
        int studentNumber;
        Teacher myTeacher;

    }
    Teacher.java
    public class Teacher {

        String name;
        int id;
        String course;
    }

3.6 知识准备:方法的声明

类的定义中还可以包含方法的声明,Java的方法决定了对象可以接收什么样的信息,方法的基本组成部分包括名称、参数、返回值和方法体。其语法规则如下:

< modifiers> <return_type> <name>([< argu_list>]) {
        [< method body>]
    }

其中:

● < modifiers>为修饰符,可用的有public、private、protected、abstract、static和final,用于说明方法的属性。

● <return_type>是该方法的返回值类型,可以是任何合法的Java数据类型。

● <name>是方法名。

● <argu_list>是方法的参数列表,包括要传给方法的信息的类型和名称,如有多个参数,中间用逗号“,”分隔。

● <method body>是方法体,有0到多行Java语句。

下面在2.2.5节示例MyClass类中声明一个名为ChangeTeacher的方法,当大多数同学对老师不满意时,可以使用这个方法来换个给力的老师,并返回老师的名字。

public class MyClass {
        int classID;
        String className;
        int studentNumber;
        Teacher myTeacher;
        public String ChangeTeacher(Teacher t){
            System.out.print("change a teacher");
            this.myTeacher = t;
            return t.name;
        }
    }

注意:

1.参数列表传递的实际上是引用,引用的对象类型必须和参数类型一致,不然编译器会报错。

2.Java语言中类、方法及属性声明的次序并无严格要求。

3.7 知识准备:构造器(构造方法)

在Java程序中,每个类都必须至少有一个构造器(Constructor)。构造器是创建一个类的实例(对象)时需要调用的一个特殊的方法。

利用构造器可以产生一个类的实例,并且提供了一个地方用来定义创建类的实例时都需要执行的初始化(initialize)代码。构造器的定义语法如下:

<modifier> <class_name> ( [<argument_list>] )
        {
        [<statements>]
    }

从上面的语法中可以看出,它和类中的方法定义很类似:可以有访问修饰符modifier、有自己的方法名称、有参数列表、有方法体,因此,可以将构造器当成一个特殊的方法(在许多资料里面,就是将Constructor称为构造方法),这个方法的作用就是用来产生一个类的实例。但是要认识到构造器与普通方法的区别,主要表现在以下3个方面。

(1)修饰符:和方法一样,构造器可以有任何访问的修饰:public、protected、private或者没有修饰。不同于方法的是,构造器不能有以下非访问性质的修饰:abstract、final、native、static或者 synchronized。

(2)返回值:方法能返回任何类型的值或者无返回值(void),构造器没有返回值,也不需要void。

(3)命名:构造器使用和类相同的名字,通常为名词。而方法则不同,通常为描述一个操作的动词。按照习惯,方法通常用小写字母开始,而构造器通常用大写字母开始。

下面定义一个用来表示“美食”的类Food。

源文件:Food.java


public class Food {
        private String food_name ;
        public Food(String name){
            this.food_name = name;
        }
    }

在Food类中,定义了一个属性food_name,还定义了一个构造器,在构造器中传入一个字符串类型的参数,将参数值赋给属性food_name。此时,就可以通过这个构造器来实例化这个类,如下所示。

Food myDinner = new Food("pizza");

这样,就得到了一个food_name名为“pizza”的实例,还可以再创建一个food_name名为“cola”的实例来搭配你的晚餐。

如果在程序中没有定义任何的构造器,则编译器将会自动加上一个不带任何参数的构造器。默认的构造器不带任何的参数,也没有“方法体”。

通过上面的示例,在Food类中定义了一个带一个参数的构造器。如果上面的Food类没有定义构造器,则编译器会自动加上一个构造器:

public class Food {
        private String food_name ;
        public Food(){
        }
    }

所以,这时可以用下面的语句来实例化这个类:

Food myDinner = new Food();

如果在程序中定义了构造器,则编译器将不再提供默认的构造器,即使定义的构造器同样没有参数。如果再使用默认构造器的话,编译器会报错。

3.8 知识准备:对象的创建和使用

正确声明了Java类之后,便可以在其他的类或应用程序中使用该类了。使用类是通过创建该类的对象并访问对象成员来实现的。对象成员是指一个对象所拥有的属性或可以调用的方法,现阶段可以理解为对象所属的类中定义的所有属性和方法。一个对象的声明实际上只是对该类的引用,需要使用new+构造器(又称为构造方法)创建对象,此时存储器会给此对象相应的存储空间。当对象被成功创建后,可以使用“对象名.对象成员”的方式访问对象成员。

3.9 任务一:创建并引用一个对象

1.任务描述

创建一个美食类,并引用该类的对象,列出一天的食谱。

2.技能要点

(1)声明类、属性及方法。

(2)对象的创建和引用。

3.任务实现过程

(1)定义一个用于表示“食物”的类“Food”;在类中声明一个food_name属性;给food_name属性添加get()、set()方法。

(2) 在Recipe类中,通过默认构造方法创建3个 “Food”对象,通过setFood_name(String name)方法给food_name赋值,并通过 getFood_name()方法获得food_name属性值,并输出。

源文件:Recipe.java


public class Recipe {
        public static void main(String args[]) {
            Food breakfast = new Food();
            breakfast.setFood_name("bread");
            Food lunch = new Food();
            lunch.setFood_name("nuddle");
            Food dinner = new Food();
            dinner.setFood_name("pizza");
            System.out.print("my breakfast is "+breakfast.getFood_name()+"\n");
            System.out.print("my lunch is "+lunch.getFood_name()+"\n");
            System.out.print("my dinner is "+dinner.getFood_name());
        }
    }
    class Food {
        private String food_name ;

        public String getFood_name() {
            return food_name;
        }
        public void setFood_name(String foodName) {
            food_name = foodName;
        }
    }

程序运行结果:

my breakfast is bread
    my lunch is nuddle
    my dinner is pizza

3.10 技能拓展任务:带参数构造器的声明与使用

1.任务描述

改写任务一的程序,使用带参数构造器,实现同样的输出结果。

2.技能要点

带参数构造器的声明和引用。

3.任务实现过程

(1)定义一个用于表示“食物”的类“Food”;在类中声明一个food_name属性;给food_name属性添加get()、set()方法。

(2)给Food类添加两个构造方法,一个带参数,一个不带参数。

(3)在Recipe类中,通过带参数构造方法创建两个“Food”对象,通过getFood_name()方法获得food_name属性值,并输出。

(4)在Recipe类中,通过不带参数构造方法创建一个“Food”对象,通过setFood_name(String name)方法给food_name赋值并输出。

源文件:Recipe.java


public class Recipe {
        public static void main(String args[]) {
            Food breakfast = new Food("bread");
            Food lunch = new Food("noddle");
            Food dinner = new Food();
            dinner.setFood_name("pizza");
            System.out.print("my breakfast is "+breakfast.getFood_name()+"\n");
            System.out.print("my lunch is "+lunch.getFood_name()+"\n");
            System.out.print("my dinner is "+dinner.getFood_name());
        }
    }
    class Food {
        private String food_name ;

        public String getFood_name() {
            return food_name;
        }
        public void setFood_name(String foodName) {
            food_name = foodName;
        }
        public Food(String name){
            this.food_name = name;
        }
        public Food(){}
    }

程序运行结果:

my breakfast is bread
    my lunch is nuddle
    my dinner is pizza

本文选自华清远见android开发培训教材《Android系统下Java编程详解》

 更多相关文章

·Android开发环境搭建
·Android开发框架
·Android系统架构
·Android系统介绍及平台特性
·Android开发之Frame动画实现方法