二、面向对象编程(一)
2.1面向对象概述
面向对象的三种基本特征:继承、多态和封装。Java因为满足这三种面向对象的特征,被称为纯粹的面向对象程序设计语言。其完全以对象为中心,Java的最小单位是类,整个Java程序由一个一个类组成。
java完全支持使用对象、类、继承、封装、消息等基本概念来进行程序设计,允许从现实世界客观存在的事物出发构造软件系统,在构造中尽可能运用人类的思维方式。面向对象的方式实际上是由OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)三个部分有机组成。其中,OOA、OOD的结构需要使用一种方式来描述记录,目前业界统一使用UML(统一建模语言)来描述记录OOA、OOD的结果。关于UML,这里不过多解释,感兴趣的同学可以查看以下网页或者查阅资料了解。
https://baike.baidu.com/item/%E7%BB%9F%E4%B8%80%E5%BB%BA%E6%A8%A1%E8%AF%AD%E8%A8%80/3160571
目前软件开发领域用两种主流的开发方法:结构化开发方法和面向对象开发方法。面向对象语言与面向结构化语言相比优点是可重用性、可扩展性和可维护性。
2.2类和对象
类是封装对象的属性和行为的载体,而在Java语言中对象的属性以成员变量形式存在,对象的方法以成员方法形式存在。
java中定义类的简单语法如下:
[修饰符] class 类名
{
零个到多个构造器……
零个到多个成员变量……
零个到多个方法……
}
在上面的语法格式中修饰符可以是public、final、abstract,或者完全省略这三个修饰符。类名只要是一个合法的标识符即可。
每个文件只能有一个修饰符为public的类。
被final修饰的类不可被继承;
abstract修饰抽象类,我们后面会介绍。
类里各成员之间的定义顺序没有任何影响,各成员之间可以相互调用,但是static修饰的变量不能访问没有static修饰的成员。
构造器是一个类创建对象的根本途径,如果一个类没有构造器,这个类通常无法创建实例。为此,java提供了一个功能:如果一个程序员没有为一个类创建构造器,系统会创建一个自动的构造器。但如果程序员创建了一个构造器,系统则不提供该构造器。
(1)成员变量
在Java中,对象的属性也称成员变量,成员变量可以是任意类型,成员变量就是普通变量可以为其初始化,也可以不初始化。以下是定义一个成员变量的语法:
[修饰符] 类型 成员变量名[=默认值];
修饰符:可省略,也可以是public,static,protect,private,final其中public,protect,private只能出现其中之一,可以与static,final共同修饰成员变量。
类型:类型可以是Java语言允许的任何数据类型,包括基本类型和现在介绍的引用类型。
成员变量名只要是一个合法的标识符即可;
默认值:定义成员变量还可以指定一个可选的默认值。
(2)成员方法
定义方法的语法格式如下
[修饰符] 方法返回值类型 方法名(形参列表)
{
//方法体
}
修饰符:public,private,protect,static,final,abstract。修饰符的其他要求与成员变量相似,但final、abstract两者只能出现一次。
返回值类型:如果方法没有返回值,则必须使用void来声明没有返回值。如果有返回值,则方法体内必须有return语句返回。
形参列表:形参列表用于定义该方法可接受的参数,形参列表由零到多组”参数类型 形参名“组合而成多组参数之间以英文逗号隔开(,)。
static是一个特殊的关键字,它可用于修饰方法、成员变量等成员。static修饰的成员表明它属于这个类本身,,而不属于这个类的单个实例,因此通常把static修饰的变量和方法也成为类变量、类方法。不使用static修饰的普通方法、成员变量则属于这个类的单个实例,而不属于该类。因此把不用static修饰的称为实例变量、实例方法。
(3)权限修饰符
private,protected,public,这些修饰符控制着对类和类的成员变量以及成员方法的访问.如果一个类的成员变量和成员方法被修饰为private,则该成员变量只能在本类中被使用,在子类或者其他包的类是不可见的。如果一个类的访问权限设置为private,这个类将隐藏其内的所有数据,以免用户直接访问它。如果一个类需要使类中的数据被子类或其他包中的类调用,可以将这个类设置为public访问权限。如果一个类使用protected修饰符,那么只有本包内的该类的子类或其他类可以访问此类中的成员变量和方法。
访问包位置 | 类修饰符 | ||
private | protected | public | |
本类 | 可见 | 可见 | 可见 |
同包其他类或子类 | 不可见 | 可见 | 可见 |
其他包的类或子类 | 不可见 | 不可见 | 可见 |
当声明类时不使用public、protected和private修饰符设置类的权限,则这个类预设为包存取范围,即只有一个包中的类可以访问这个类中的成员变量或成员方法。
例如,在项目的com.mr包下创建AnyClass类,该类使用默认的访问权限。
package com.mr;
class AnyClass{
public void doString()
……//方法体
}
在上述代码中,由于类的修饰符为默认修饰符,即只有一个包内的类或其他子类可以对该类进行访问,而AnyClass类中的doString()方法却又被设置为public访问权限,即使这样,doString()方法的访问权限,即使这样doString()方法访问权限依然与AnyClass类的访问权限相同。
(4)构造方法(构造器)
构造方法是没有返回值的,定义语法如下:
[修饰符] 构造器名(形参列表)
{
//由零条到多条的可执行性语句组成的构造体执行体
}
构造体既不能定义返回值类型,也不能使用void声明构造器没有返回值。如果为构造器定义了返回值,或使用了void声明构造器没有返回值,编译时虽然不会出错,但Java会把它当作方法来处理,就不是构造方法了。
构造方法的名称要与本类的名称相同。
(5)对象的产生和使用
创建对象的哥们根本途径是构造器,通过new关键字来调用某个类的构造器即可创建这个类的实例。
//使用Person类定义一个Person类型的变量
Person p;
//通过new关键字调用Person类的构造器,返回一个Person实例
//将Person实例赋值给p变量
p=new Person();
上面代码也可写成以下形式:
Person p=new person();
//定义p变量的同时给p变量赋值
创建对象之后就可以使用对象了,Java中的对象大致有以下作用:
访问对象的实例变量
调用对象的方法
如果访问权限允许,类里定义的方法和成员变量都可以通过类或实例来调用。类或实例来调用。类或实例访问方法或成员变量的语法是:类.类变量|方法,或者实例.实例方法|变量,在这种方式中,类或实例是主调者,用于访问该类或该实例的成员变量或成员方法。
static修饰的方法或成员变量,既可以通过类来调用也可以通过实例来调用:没有使用static修饰的普通方法和成员变量,只可通过实例来调用。下面代码中通过Person实例来调用Person的成员变量和方法
//访问p的name实例变量,直接为该变量赋值
p.name="ligang";
//调用p中的say()方法时,声明say()方法时定义了一个形参
//调用该方法必须为形参指定一个值
p.say=("Java语法很简单,学习很容易i");
//直接输出p的实例变量,将输出 李刚
Sysetm.out.println(p.name);
上述代码中通过Person实例调用了say()方法,调用方法时必须为该方法的形参赋值。因此在这行代码中调用say()方法时,必须为say()方法传入一个字符串作为形参的参数值,这个字符串将被赋值给content参数。
(6)this关键字
this关键字用于表示本类当前的对象,当前对象不是某个new出来的实体对象,而是当前正在编辑得类,this关键字只能在本类中使用。例如
public void setName(String name)//定义一个setName()方法
{
this.name=name;//将参数赋值给类中的成员变量
}
在上述代码中,this.name指的是Book类中的name成员变量,而this.name=name语句中第二个name指的是形参name。实质上setName()方法的作用就是将形参name的值赋给成员变量name。
this关键字可以理解为java中的一个指针,this关键字总是指向调用该方法的对象。根据出现位置的不同,this作为对象默认引用有两种情形:
构造器中引用该构造器正在初始化的的对象
在方法中引用调用该方法的对象
this关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或实力变量。假设定义了一个Dog类的run()方法需要调用它的jump()方法:
第一种,定义Dog类:
public class Dog{
public void jump()
{
System.out.println("running jump");
}
public void run()
{
Dog d=new Dog();
d.jump();
System.out.println("running run");
}
}
public class DogTest
{
public static void main(String[] args)
{
Dog d=new Dog();
dog.run();
}
}
将前面的Dog类的run()方法改为如下方式更合适
public void run
{
this.jump();
System.out.prinntln("running run");
}
从前一种来看,在Dog对象里run()方法内重新创建了一个新的Dog对象,并调用它的jump()方法,这意味着一个Dog对象的run()方法需要依赖另一个对象的jump()方法,这不符合实际。上面的代码跟符合实际,run()方法依赖于他自己的jump()方法。
在static修饰的方法中,不能用this关键字,static可以直接用类调用它的方法,用this时无法指向合适的对象,所以static修饰的对象不能访问不使用static修饰的普通成员。因此,Java语法规定:静态成员不能直接访问非静态成员。
(7)方法的重载
JAVA允许同一个类里定义多个同名方法,只要形参列表不同就可以。如果一个类中包含了两个或两个哟上的方法名相同,但形参列表不同,则称为方法的重载。
如:
public class Overload
{
public void test()
{
Syystem.out.println("decgb");
}
public void test(String mag)
{
System.out.println("方法重载"+mag);
}
public static void main(String[] arggs)
{
Overload ol=new Overload();
ol.test();
ol.test("hello");
}
}