1. 方法的所属
方法是类或对象的行为特征的抽象,方法是类或对象最重要的组成部分。在逻辑上要么属于类,要么属于对象。从功能上看,方法完全类似于传统结构化程序设计里的函数。实际上,方法确实是传统的函数发展而来。
方法和函数的区别:
1. 在结构化编程语言中:函数是一等公民,整个软件是由一个个的函数组成。
2. 在面向对象编程语言中:类才是一等公民,整个系统由一个个类组成,因此在java中方法不能独立存在。
方法必须属于类或对象。
因此,如果需要定义方法,则只能在类体中定义,不能独立定义一个方法。java里的方法不能独立存在,它必须属于一个类过着一个对象,因此方法不能像函数那样被独立执行,必须使用类或者对象来作为调用者。
同一个类里不同方法之间相互调用时,是直接调用的吗?
同一个类的一个方法调用另外一个方法时,如果被调用的方法是普通方法,会默认使用this作为调用者;如果被调用的方法是static静态方法,则默认使用类作为调用者。也就是说,表面上看起来某些方法可以被独立执行,但实际上还是使用this或者类来作为调用者。
2. 成员方法
成员方法就是指在类体中定义的方法,用于描述该类事物的行为信息,换句话说,成员方法就是对语句块的打包,从而实现代码的复用,提高代码的可维护性。
[修饰符] 方法返回值类型 方法名(形参列表){
方法体;
}
修饰符:public、protected、private、static、final、abstract
abstract和final最多只能出现其一;可以和static组合起来修饰属性。
方法返回值类型:如果声明了方法返回值类型,则方法体中必须有一个有效的return语句;否则用void。
【static】修饰的成员表明它属于这个类本身,而不熟该类的单个实例。通常把static修饰的成员变量和方法也成为类变量,类方法。静态成员不能直接访问非静态成员。
3. 构造方法(构造器)
构造方法是一种特殊的方法,使用new关键字构造对象时,会自动调用构造方法来进行成员变量的初始化工作。
默认的构造方法:
构造方法是一个类创建对象的根本途径,如果一个类没有构造器,这个类通常无法创建实例。
因此,任何一个编译后的类都必须含有构造方法。如果源程序中没有定义,编译器在编译时将为其自动添加一个无参的空构造方法(称之为“默认/缺省构造方法”)。例如,Point() {}
当定义了构造方法后,JAVA编译器将不再添加默认的构造方法
[修饰符] 类名 (形参列表){ //修饰符 public、protected、private
super();
//构造器执行体;
}
Point(int m,int n){ //构造方法的名称必须与类名相同
this.x = m;
this.y = n;
}
Point p = new Point(100, 200); //事实上,new关键字后面是调用构造方法来对成员变量进行初始化。
备注:构造器不能定义返回值类型声明,也不能使用void定义构造器没有返回值。如果为构造器定义了返回值类型,或者使用void定义构造器没有返回值,编译不会出错,但java会把这个所谓的构造器当成方法来处理。即该方法已不再是构造器。
构造器不是没有返回值吗?为什么不能用void声明?
简单的说,这是java的语法规定。实际上,类的构造器是有返回值的,当使用new关键字来调用构造器时,构造器返回该类的实例,可以吧这个类的实例当做构造器的返回值,因此构造器的返回值类型总是当前类,无需定义返回值类型。但需要注意,不要在构造器里显式的使用return来返回当前类的对象,因为构造器的返回值是隐式的。
4. 方法重载(overload)
在java语言中,一个文件允许多个方法的名称相同,但参数列表不同,称之为方法的重载(overload)。
编译器在编译时会根据其参数列表的不同,绑定到不同的方法。返回值类型可以相同也可以不同,最好还是相同。
5. 方法重写(Override)
方法重写可以理解为方法覆盖。
子类扩展了父类,子类是一个特殊的父类。大部分时候,子类总是以父类为基础,额外增加新的成员变量和方法。
有些方法从父类继承过来但不太适合子类直接使用,子类可以使用方法重写(覆盖)去改变父类继承过来的方法。
5. 1 方法重写的原则
- 两同:方法名相同,参数列表相同。
- 两小:子类方法返回值类型比父类更小或相等,子类方法声明抛出的异常比父类更小或相等。
- 一大:子类方法的访问权限比父类的更大或相等。
- 覆盖方法和被覆盖方法要么都是类方法,要么都是实例方法。
在子类重写的方法中,可以通过super关键字调用父类的“原始”方法。
但如果父类的方法为private修饰,则子类无法访问该方法,也无法重写该方法。
@Override //【标注】 告诉编译器下面的方法是对父类中方法的重写版本
public void show(){ //若没有构成重写,则编译报错
super.show();
System.out.println("color:" + getColor());
}
5. 2 static方法的重写
即:当父类中的方法以static为修饰符时,在子类中进行方法重载后,使用父类进行创建对象的引用时,调用的方法仍是父类的方法。不会调用子类中的方法。
普通方法重载后,调用的为子类中的方法。
5. 3 方法重写和重载的区别
方法重载Overload:在同一个类中,方法的名字相同,但参数个数、参数的类型或返回值类型不同!
方法重写Override:指子类和父类之间子类重写了父类的方法,但方法名、参数类型、参数个数必须相同!
5. 4 内存中的覆盖原理
当程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为它从父类继承得到的所有实例变量分配内存,即使子类定义了与父类中同名的实例变量。
如果在子类中定义了与父类中已有的变量同名的变量,那么子类中定义的变量会隐藏父类中定义的变量。注意不是完全覆盖,因此系统在创建子类对象时,依然会为父类中定义的、被隐藏的变量分配内存空间。
当需要在子类中访问或调用父类中定义的、被隐藏、覆盖的实例变量,可以通过super. 作为限定来调用。
6. 递归方法
一个方法体内调用它自身,被称为方法递归。方法递归包含了一种隐式的循环,它会重复的执行代码,但这种重复执行无须循环控制。
public class digui{
int fa(int n){
if(n==1) return 1;
return (n * fa(n-1));
}
public static void main(String[] args){
digui begin = new digui();
System.out.println(begin.fa(5));
}
}