那么什么是方法呢?
Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
方法的命名规则
- 1.方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
- 2.下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test<MethodUnderTest>_<state>,例如 testPop_emptyStack。
形参&实参
方法的定义可能会用到 参数(有参的方法),参数在程序语言中分为:
- 实参(实际参数,Arguments):用于传递给函数/方法的参数,必须有确定的值。
- 形参(形式参数,Parameters):用于定义函数/方法,接收实参,不需要有确定的值。
String hello = "Hello!";
// hello 为实参
sayHello(hello);
// str 为形参
void sayHello(String str) {
System.out.println(str);
}
1、方法的定义
一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; }
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
注意: 在一些其它语言中方法指过程和函数。一个返回非void类型返回值的方法称为函数;一个返回void类型返回值的方法叫做过程。
实例
下面的方法包含 2 个参数 num1 和 num2,它返回这两个参数的最大值。
/** 返回两个整型变量数据的较大值 */
public static int max(int num1, int num2) {
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
2、void 关键字
一个void方法的调用一定是一个语句。 所以,它被在main方法第三行以语句形式调用。就像任何以分号结束的语句一样。
3、构造方法
当一个对象被创建时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值。
通常会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来创建一个完整的对象。
不管你是否自定义构造方法,所有的类都有构造方法,因为 Java 自动提供了一个默认构造方法,默认构造方法的访问修饰符和类的访问修饰符相同(类为 public,构造函数也为 public;类改为 protected,构造函数也改为 protected)。
一旦你定义了自己的构造方法,默认构造方法就会失效。
实例
下面是一个使用构造方法的例子:
// 一个简单的构造函数
class MyClass {
int x;
// 以下是构造函数
MyClass() {
x = 10;
}
}
4、继承extends
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
1、经理:成员变量:工号,姓名,工资,管理奖金 成员方法:工作(管理其他人)、吃饭(吃米饭)
2、厨师:成员变量:工号,姓名,工资 成员方法:工作(炒菜)、吃饭(吃米饭)
父类-Employee类:
package com.test.zhigong;
public class Employee {
private String id;
private String name;
private double salary;
public Employee() {
}
public Employee(String id, String name, double salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
// 工作
public void work() {
System.out.println("员工在工作!");
}
// 吃饭
public void eat() {
System.out.println("吃米饭!");
}
}
Manager类:
package com.test.zhigong;
public class Manager extends Employee{
private double bouns; // 奖金
public Manager() {
}
public Manager(String id, String name, double salary, double bouns) {
super(id, name, salary);
this.bouns = bouns;
}
public double getBouns() {
return bouns;
}
public void setBouns(double bouns) {
this.bouns = bouns;
}
@Override
public void work() {
System.out.println("经理管理员工!");
}
}
Cook类:
package com.test.zhigong;
public class Cook extends Employee{
public Cook() {
}
public Cook(String id, String name, double salary) {
super(id, name, salary);
}
@Override
public void work() {
System.out.println("厨师在炒菜!");
}
}
Test执行类:
package com.test.zhigong;
public class Test {
public static void main(String[] args) {
Manager m = new Manager("hw001","张三",15000,3000);
System.out.println(m.getId()+ "," + m.getName()+ "," + m.getSalary()+ "," +m.getBouns());
m.eat();
m.work();
Cook c = new Cook();
c.setId("hw002");
c.setName("陈乔恩");
c.setSalary(1000000);
System.out.println(c.getId() + "," +c.getName() + "," +c.getSalary());
c.eat();
c.work();
}
}
继承的特性
- 子类拥有父类非 private 的属性、方法。
- 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。
- 子类可以用自己的方式实现父类的方法。
- Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。
- 提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
5、重写(Override)
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
方法的重写规则
- 参数列表与被重写方法的参数列表必须完全相同。
- 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。
- 父类的成员方法只能被它的子类重写。
- 声明为 final 的方法不能被重写。
- 声明为 static 的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个类,则不能重写该类的方法。
当需要在子类中调用父类的被重写方法时,要使用 super 关键字
父类狗Dog:
package com.test.extendemo;
public class Dog{
public void eat() {
System.out.println("狗在吃骨头!");
}
public void drink() {
System.out.println("狗在喝水!");
}
public void lookHome() {
System.out.println("狗在看家!");
}
}
中华田园犬ChineseDog类:
package com.test.extendemo;
public class ChineseDog extends Dog{
// 父类中的方法不能满足我们的需求,所以需要重写。 而且中华田园犬完全用不到父类中的代码,所以不需要通过调用super进行调用
@Override
public void eat() {
System.out.println("中华 田园犬吃剩饭!");
}
}
沙皮犬 SharPei类:
package com.test.extendemo;
public class SharPei extends Dog{
// 沙皮犬吃狗粮+骨头,父类方法无法满足我们需求了,所以需要重写
@Override
public void eat() {
super.eat();
System.out.println("沙皮犬啃骨头!");
}
}
哈士奇狗 HuskyDog类:
package com.test.extendemo;
public class HuskyDog extends Dog{
public void breakHome() {
System.out.println("哈士奇又在拆家了!");
}
}
对象调用:
package com.test.extendemo;
public class TestDog {
public static void main(String[] args) {
// 创建对象并调用
HuskyDog hg = new HuskyDog();
hg.eat();
hg.drink();
hg.lookHome();
hg.breakHome();
SharPeiDog sp = new SharPei();
sp.eat();;
sp.drink();
sp.lookHome();
}
}
class Dog extends Animal {
void eat() {
System.out.println("dog : eat");
}
void eatTest() {
this.eat(); // this 调用自己的方法
super.eat(); // super 调用父类方法
}
}
6.、重载(Overload)
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。
重载规则:
- 被重载的方法必须改变参数列表(参数个数或类型不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
7、多态
多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作
多态性是对象多种表现形式的体现。
现实中,比如我们按下 F1 键这个动作:
- 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
- 如果当前在 Word 下弹出的就是 Word 帮助;
- 在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。
多态调用成员的特点:
- 变量调用:编译看左边,运行看左边
- 方法调用:编译看左边,运行看右边
package com.test.duotai;
public class AnimalTest {
public static void main(String[] args) {
// 创建对象
Animal a = new Dog();
// • 变量调用:编译看左边,运行看左边
System.out.println(a.name);
// • 方法调用:编译看左边,运行看右边
a.eat();
// 多态弊端: 不能调用子类特有方法 a.lookHome(),编译时-先看父类有没有该方法,没有就报错
// 强制转换
Dog d = (Dog)a;
d.lookHome();
}
}
class Animal{
String name = "动物..";
public void eat() {
System.out.println("动物吃东西!");
}
}
class Dog extends Animal{
String name = "狗";
@Override
public void eat() {
System.out.println("狗吃骨头!");
}
public void lookHome() {
System.out.println("狗看家!");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃小鱼干!");
}
public void catchMouse() {
System.out.println("猫抓老鼠!");
}
}
动物......
狗吃骨头!
狗看家!
8、finalize() 方法
final关键字
final 含义为 "最终的"。final 可以用来修饰变量(包括类属性、对象属性、局部变量和形参)、方法(包括类方法和对象方法)和类。
使用 final 关键字声明类,就是把类定义定义为最终类,不能被继承,或者用于修饰方法,该方法不能被子类重写:
final修饰常量, 常量命名规范:单词全部大写、单词之间用下划线, final修饰的变量是基本类型-变量存储的数据值不能发生变化;修饰引用类型-变量存储的地址值不能改变,对象内部可以改变
- 声明类:
final class 类名 {//类体}
- 声明方法:
修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}
注: final 定义的类,其中的属性、方法不是 final 的。
finalize()方法
Java 允许定义这样的方法,它在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。
例如,你可以使用 finalize() 来确保一个对象打开的文件被关闭了。
在 finalize() 方法里,你必须指定在对象销毁时候要执行的操作。
finalize() 一般格式是:
protected void finalize()
{
// 在这里终结代码
}
关键字 protected 是一个限定符,它确保 finalize() 方法不会被该类以外的代码调用。
当然,Java 的内存回收可以由 JVM 来自动完成。如果你手动使用,则可以使用上面的方法。
9、抽象类abstract
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
快捷键---ARLT+回车
Animal类:
package com.test.abstracts;
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
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 void drink() {
System.out.println("动物喝水!");
}
// abstract抽象方法
public abstract void eat();
}
Dog类:
package com.test.abstracts;
public class Dog extends Animal{
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨头!");
}
}
Sheep类:
package com.test.abstracts;
public class Sheep extends Animal{
public Sheep() {
}
public Sheep(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("小羊吃草!");
}
}
Test类:
package com.test.abstracts;
public class Test {
public static void main(String[] args) {
Dog d = new Dog("小灰灰" + ",年龄:",2);
System.out.println(d.getName() + "," + d.getAge());
d.eat();
d.drink();
}
}