文章目录
# 类与方法
面向对象概述
-
面向机器语言
计算机处理信息的早期语言是所谓的机器语言,使用机器语言进行程序设计需要面向机器来编写代码,即需要针对不同的机器编写诸如0101 1100这样的指令序列。
-
面向过程语言
随着计算机硬件功能的提高,在20世纪60年代出现了面向过程设计语言,如C语言等。用这些语言编程也称为面向过程编程。语言把代码组成叫做过程或函数的块。每个块的目标是完成某个任务。使用这些语言编写代码指令时,不必再去考虑机器指令的细节,只要按着具体语言的语法要求去编写“源文件”。
-
面向对象语言
基于对象的编程更加符合人的思维模式,使得编程人员更容易编写出易维护、易扩展和易复用的程序代码,更重要的是,面向对象编程鼓励创造性的程序设计。
面向对象编程主要体现三个特性:封装性 ;继承;多态
类与对象
- Java语言是面向对象语言,它的源程序是由若干个类组成,源文件是扩展名为 .java 的文本文件。
- 类是Java语言中最重要的“数据类型”,类声明的变量被称作对象,即类是用来创建对象的模板。
- 类的实现包括两部分:类声明和类体。基本格式为:
class 类名 {
//类的成员变量
//类的成员方法
//类体的内容等
}
成员变量
在 Java 中对象的属性也称为成员变量,成员变量的定义与普通变量的定义一样,语法如下:
数据类型 变量名称[=值]
其中,[=值]表示可选内容,定义变量时可以为其赋值,也可以不为其赋值。如果不设置初始值,则会有默认值。
类及其成员变量的定义示例:
public class Bird{
String wing; //翅膀
String claw; //爪子
String beal; //喙
String feather; //羽毛
}
成员方法
- 成员方法的定义,语法格式如下:
[权限修饰符] [返回值类型]方法名([参数类型 参数名])[throws 异常类型]{
//方法体
return 返回值;
}
-
权限修饰符可以是 private、public,protected中的任意一个,也可以不写,主要用来控制方法的访问权限;
-
返回值类型用来指定方法返回数据的类型,可以是任何类型,如果方法不需要返回值,则使用void关键字;
-
一个成员方法既可以有参数,也可以没有参数,参数可以是对象,也可以是基本数据类型的变量。
-
注∶方法的定义必须在某个类中,定义方法时如果没有指定权限修饰符,方法的默认访问权限为缺省(即只能在本类及同一个包中的类中进行访问)。
- 成员方法的参数
调用方法时可以给该方法传递一个或多个值,传给方法的值叫作实参,在方法内部,接收实参的变量叫作形参,形参的声明语法与变量的声明语法一样。形参只在方法内部有效。
Java中方法的参数主要有3 种,分别为值参数、引用参数和不定长参数:
-
值参数
值参数表明实参与形参之间按值传递,当使用值参数的方法被调用时,编译器为形参分配存储单元,然后将对应的实参的值复制到形参中,由于是值类型的传递方式,所以,在方法中对值类型的形参的修改并不会影响实参。
-
引用参数
如果在给方法传递参数时,参数的类型是数组或者其他引用类型,那么,在方法中对参数的修改会反映到原有的数组或者其他引用类型上,这种类型的方法参数被称之为引用参数。
-
不定长参数
声明方法时,如果有若干个相同类型的参数,可以定义为不定长参数,该类型的参数声明为∶
权限修饰符 返回值类型 方法名(参数类型... 参数名)
,其中参数类型和参数名之间是三个点,而不是其他数量或省略号。
构造方法
在类中除了成员方法之外,还存在一种特殊类型的方法,那就是构造方法。**构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。**每当类实例化一个对象时,类都会自动调用构造方法。 构造方法的特点如下∶
- 构造方法没有返回类型,也不能定义为void;
- 构造方法的名称要与本类的名称相同;
- 构造方法的主要作用是完成对象的初始化工作,它能把定义对象的参数传给对象成员。
构造方法的定义语句代码如下:
class Book{
public Book(){ //(无参)构造方法
}
}
在构造方法中可以为成员变量赋值,这样当实例化一个本类的对象时,相应的成员变量也将被初始化。如果类中没有明确定义构造方法,则编译器会自动创建一个不带参数的默认构造方法。
除此之外,在类中定义构造方法时,还可以为其添加一个或者多个参数,即有参构造方法,语法如下:
class Book {
public Book(int args){ //有参构造方法
//对成员变量进行初始化
}
}
this关键字
如果方法中出现了与局部变量同名的参数,会导致方法无法直接使用成员变量。
Java语言中规定使用this关键字来代表本类对象的引用,this关键字被隐式地用于引用对象的成员变量和方法。此外,它还可以调用类中的构造方法。
实例
创建一个借书类BorowABook
,借书类中有书名属性name
,参数为name
的构造方法和借书方法borrow()
。编写一个程序,使用this
关键字调用书名属性后,借阅《战争与和平》这本书。代码如下∶
public class BorrowABook { // 创建借书类
String name; // 属性:书名
public BorrowABook(String name) { // 参数为name的构造方法
this.name = name; // 将参数name的值付给属性name
}
public void borrow() { // 借书方法
System.out.println("请前往借阅登记处领取" + name + "。"); // 输出借出的书名
}
public static void main(String[] args) {
// 创建参数为“《战争与和平》”的借书类对象,
BorrowABook book = new BorrowABook("《战争与和平》");
book.borrow(); // 调用借书方法
}
}
- this关键字虽然可以调用成员变量和成员方法,但Java语言中最常规的调用方式是使用"对象.成员变量"或"对象.成员方法"进行调用;
- this关键字除了可以调用成员变量或成员方法之外,还可以作为方法的返回值。 例如,在项目中创建一个类文件,在该类中定义Book类型的方法,并通过过this关键字进行返回。
public class Book{
public getBook(){
return this; //返回Book类引用
}
}
在getBook()
方法中,方法的返回值为Book
类,所以方法体中使用return this
这种形式将Book
类的对象进行返回。
static 关键字
由static修饰的变量、常量和方法分别被称作静态变量、静态常量和静态方法,也被称作类的静态成员。
静态变量
很多时候,不同的类之间需要对同一个变量进行操作。在Java程序中,如果把共享的变量用static修饰,那么该变量就是静态变量。 调用静态变量的语法如下∶
类名.静态类成员
静态方法
如果想要使用类中的成员方法,需要先将这个类进行实例化,但有些时候不想或者无法创建类的对象时,还要调用类中的方法才能够完成业务逻辑,这种情况下就可以使用静态方法。 调用类的静态方法语法如下∶
类名.静态方法();
实例
创建一个水池类,使用静态变量表示水池中的水量,并初始化水池中的水量为0,通过注水方法(一次注入3个单位)和放水方法(一次放出2个单位),控制水池中的水量。代码如下∶
public class Pool { // 创建水池类
public static int water = 0; // 初始化静态变量之水池中的水量为0
public static void outlet() { // 放水,一次放出2个单位
if (water >= 2) { // 如果水池中的水量大于等于2个单位
water = water - 2; // 放出2个单位的水
} else { // 如果水池中的水量小于2个单位
water = 0; // 水池中的水量为0
}
}
public static void inlet() { // 注水,一次注入3个单位
water = water + 3; // 注入3个单位的水
}
public static void main(String[] args) {
System.out.println("水池的水量:" + Pool.water); // 输出水池当前水量
System.out.println("水池注水两次。");
Pool.inlet(); // 调用静态的注水方法
Pool.inlet(); // 调用静态的注水方法
System.out.println("水池的水量:" + Pool.water); // 输出水池当前水量
System.out.println("水池放水一次。");
Pool.outlet(); // 调用静态的放水方法
System.out.println("水池的水量:" + Pool.water); // 输出水池当前水量
}
}
静态代码块
在类的成员方法之外,用static修饰代码区域可以称之为静态代码块。定义一块静态代码块,可以完成类的初始化操作,在类声明时就会运行。 语法如下∶
public class StaticTest {
static {
// 此处编辑执行语句
}
}
实例**
创建静态代码块、非静态代码块、构造方法、成员方法,查看这几处代码的调用顺序。代码如下:
public class StaticTest {
static String name;
// 静态代码块
static {
System.out.println(name + "静态代码块");
}
// 非静态代码块
{
System.out.println(name + "非静态代码块");
}
public StaticTest(String a) {
name = a;
System.out.println(name + "构造方法");
}
public void method() {
System.out.println(name + "成员方法");
}
public static void main(String[] args) {
StaticTest s1;// 声明的时候就已经运行静态代码块了
StaticTest s2 = new StaticTest("s2");// new的时候才会运行构造方法
StaticTest s3 = new StaticTest("s3");
s3.method();// 只有调用的时候才会运行
}
}
类的主方法
主方法是类的入口点,它指定了程序从何处开始,提供对程序流向的控制。Java编译器通过主方法来执行程序。主方法的语法如下∶
public static void main(String[] args){
// 方法体
}
- 主方法是静态的,所以如要直接在主方法中调用其他方法,则该方法必须也是静态的;
- 主方法没有返回值;
- 主方法的形参为数组,其中
args[0]~args[n]
分别代表程序的第一个参数到第n+1个参数,可以使用args.length
获取参数的个数。
继承与多态
继承
继承是面向对象编程中的特征之一,即从已有的类中派生出新的类,新的类具有父类的方法,同时也可以增加新的方法。这种特性使得复用代码非常容易,缩短开发周期。
在java中使用extends 关键字来声明子类继承于某父类,如下:
class 父类 {
}
class 子类 extends 父类 {
}
实例
- 公共父类
public class Animal {
private String name;
private int id;
public Animal(String myName) {
name = myName;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("我是" + name + ".");
}
}
- 老虎类
public class tiger extends Animal {
public Penguin(String myName) {
super(myName);
}
}
- 兔子类
public class rabbit extends Animal {
public Mouse(String myName) {
super(myName);
}
}
继承类型
继承分单继承和多重继承,Java不支持多继承。
单继承和多重继承:单继承是指一个子类最多只能有一个父类;多继承是一个子类可以有二个以上的父类。
多重继承例子如下:
public class A{}
public class B extends A{}
public class C extends B{}
继承关键字
implements
Java除了extends
,还可以用implements
关键字来实现继承。Java中不支持多重继承,但是用implements
可以实现多个接口,相当于使得Java具有多继承的特性。
public interface if1 {
public void method1();
}
public interface if2 {
public void method2();
}
public class if3 implements if1,if2 {
}
super与this
super
:引用当前对象的父类成员
this
:指向当前类的引用。
class Father {
void method() {
System.out.println("这是父类的方法");
}
}
class Son extends Father {
void method() {
System.out.println("这是子类的方法");
}
void diff_method() {
this.method();
super.method();
}
}
public class Test {
public static void main(String[] args) {
Father father = new Father();
father.method();
Son son = new Son();
son.diff_method();
}
}
final
final
的功能是将类定义为不可继承的,也可以用于修饰方法,被修饰的方法不可被子类重写。
继承的特性
- 子类不继承父类的
private
属性和方法; - 子类可以对父类进行扩展,拥有自己的属性和方法;
- 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过
super
关键字调用父类的构造器并配以适当的参数列表; - 如果父类构造器没有参数,则在子类的构造器中不需要使用
super
关键字调用父类构造器,系统会自动调用父类的无参构造器。
多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态的转型
多态的转型有向上转型和向下转型两种。
-
向上转型
当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作:
父类类型 变量名=new 子类类型()
-
向下转型
当要使用子类特有功能时:
子类类型 变量名=(子类类型) 父类类型的变量;
实例
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法,向上转型 Animal a = new Cat()
show(new Dog()); // 以 Dog 对象调用 show 方法,向上转型 Animal a = new Dog()
// Animal a = new Cat(); // 向上转型
// a.eat(); // 调用的是 Cat 的 eat
// Cat c = (Cat)a; // 向下转型
// c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}