方法5要素:修饰词、返回值类型、方法名、参数列表、方法体。
例如:public static void main(String[] args){
方法体
}
其中,public static是修饰词;void是返回值类型,main是方法名;
String[] args是参数类型和参数;被大括号包裹的是方法体。
注意事项:
(1)方法的参数可有可无,但有参数时更灵活
(2)当方法不需要返回结果时,返回值类型用void。
(3)当方法需要返回值类型时,设定返回值类型,返回值类型可以是基本类型也可以是引用类型,通过return返回结果,返回的结果必须与返回值类型匹配。无论return有无返回结果,使用了return都将结束方法体。
构造方法:常常用于给成员变量(非静态变量)初始化,初始化的是类的实例。
注意事项:
(1)方法名必须和类名相同,无返回值类型(也不用void)
(2)不能被static、final、synchornized、abstract、native修饰
(3)在创建对象的同时被自动调用
(4)若自己未写构造方法,则编译器会默认给出一个无方法体的无参构造方法。
(5)若自己写了构造方法,则编译器不会给出默认的无参构造,只能使用我们自己定义的构造方法。
静态方法:被static修饰的方法。
注意事项:
(1)这类方法没有隐式的this和super,不能使用这两关键字
(2)只能访问静态的变量和方法(用类名直接访问 ),不能直接访问实例变量和实例方法,若需访问可用间接用实例对象访问。
(3)不能和abstract连用,静态方法必须要实现。
(4)位于内存中的方法区。
(5)构造方法可以有多个重载,但不能被重写。
非静态方法:未被static修饰的方法。
和静态方法的区别:
(1)这类方法有隐式的this和super,可以使用this访问当前对象,用super访问父类对象。
(2)可以直接访问静态的变量和方法, 也可以访问非静态的变量和方法。
静态代码块:static{ 代码块 },用于对类的静态变量赋值,初始化类。
注意事项:
(1)静态代码块是属于类的代码块,主要用于对类的静态变量初始化。
(2)位于方法区中,在类加载期间执行,且只执行一次。
(3)类中不同的静态代码块会根据它们在类中出现的顺序被依次执行。
(4)静态代码块通常用于软件加载静态资源。
抽象方法:被abstract修饰的方法。用于描述系统具有什么功能,而不提供具体的实现。
注意事项:
(1)抽象方法是一个不完整的方法,没有方法体,也没有{},以分号结尾。
格式为:访问修饰词 abstract 返回值类型 方法名(参数列表);
eg:public abstract int getNumber(int a);
(2)抽象方法必须被子类实现,所以不能用private修饰。
(3)抽象方法必须包含在抽象类中。
抽象类:被abstract修饰的类
注意事项:
(1)抽象类不能被实例化。
(2)抽象类不能被private、final、static修饰
(3)如果一个类继承了抽象类,那么子类必须重写其继承的抽象方法。(不一定必须实现,仍可重新为抽象方法)
(4)一个抽象类可能不包含抽象方法,但包含抽象方法的类必定是抽象类
抽象类的意义:
(1)封装子类中的重复内容(成员变量和方法)
(2)为子类提供一个公共的类型
(3)定义有抽象方法,可以让子类重写该方法实现不同的功能
接口(interfence):一种标准或规范,是一种特殊的抽象类。
注意事项:
(1)在接口中只包含抽象方法和常量。常量的(public static final)可以省略。
(2)接口的实现是使用implements关键字。
(3)一个类实现某个接口后必须要实现该接口中的所有方法,且重写方法时,方法的修饰词应为public。
(4)一个接口可以继承另一个接口,一个类可以实现多个接口,中间用逗号分隔。
(5)当一个类既有继承,又有接口,那么先继承再实现接口
方法的重载和重写
方法的重载(overload):在同一个类中,方法名相同,参数列表不相同的方法就是方法的重载。无论返回值类型和访问修饰词如何,只要符合上述条件就是方法的重载。在编译期绑定,看类型。可以被多次重载。
方法的重写(override):在父子类中,满足“两同两小一大”条件要求的方法才算方法的重写。只能重写一次。条件如下:
两同:方法名和参数列表相同
两小:子类的返回值类型小于等于父类;子类抛出的异常小于等于父类。
一大:子类的访问权限大于或等于父类。
变量:分为静态变量和实例变量
在类中变量分为成员变量和局部变量,成员变量又分为实例成员变量和静态成员变量。
成员变量:定义在类中,由系统设置默认值,可以不显式化初始化。成员变量存储在堆中,生命周期为:实例化对象时出生,对象被回收时死亡。
局部变量:定义在方法中,不能被显式的访问修饰词(public,private,protected)和static修饰,不能通过类名或引用名访问,没有默认值,使用前必须自行设定初始化。局部变量存储在栈中。生命周期为:方法调用时出生,方法结束时从栈中清除。
静态变量:被static修饰的变量,存储在方法区中,在内存中只有一份,被所有实例共享,属于类。可以直接通过类名访问。生命周期取决于类的生命周期。
实例变量:未被static修饰,没创建一个实例,都会为实例变量分配一次内存,存储于堆中,属于对象,一个对象一份实例变量。生命周期取决于生命周期。
内存分配:堆、栈、方法区
堆:存储new出来的对象实例(包括成员变量)
栈:存储局部变量,引用。调用方法时,栈中分配该方法的栈帧,栈帧中包括参数和局部变量。当方法执行结束时,栈帧被清除,局部变量失效。
方法区:存储类的信息(.class及方法)和静态变量,方法只有一份,通过this区分对象。
<span style="font-size:14px;">package com.blogs.yuan;
public class A {
protected int a;
protected static int b;
/**
* 自定义无参构造方法,写了则编译器不再生成默认的无参构造
* @param a
*/
public A() {
a = 5;
b = 2;
}
/**
* 重载构造方法
* @param a
*/
public A(int a){
this.a = a;
}
/**
* 静态代码块,用于加载静态资源,初始化类
*/
static{
b = 1;
}
/**
* 静态方法,测试静态方法的使用
*/
public static void testStatic(){
System.out.println(b); //正确,b=1,最先加载,之后才执行其他方法
// System.out.println(a); //编译出错,不能直接访问非静态变量,a=5
A a = new A(); //使用new创建A类对象,并调用A的构造方法,将对象的地址存入引用a中
System.out.println(a.a);//通过实例变量访问非静态变量,a=7
// testNotStarct(); //不能直接访问非静态的方法
System.out.println(a.b);//可以使用实例调用静态变量,b=2
System.out.println(A.b);//可以直接用类名调用静态变量,而且一般我们都使用这种方式,b=2
}
public void testNotStatic(){
System.out.println(a); //正确,可以直接访问静态变量
System.out.println(b); //正确
testStatic(); //可以直接访问静态方法
}
//public abstract int getNumber(int a); //若存在抽象方法,那么类必须是抽象类,不能被实例化。
public static void main(String[] args) {
A a = new A(7); //调用有参构造,重载看参数列表,看类型
testStatic();
a.testNotStatic(); //a=7,b=2
A b = new B(); //向上造型
b.testNotStatic(); //方法重写,看对象,覆盖父方法,a=6,b=3
}
}
class B extends A{
//初始化B类实例
public B() {
super(); //默认调用无参构造,若父类没有无参构造则必须用super调用有参构造
this.a = a+1;
this.b = b+1;
}
//重写父类方法,并覆盖它
public void testNotStatic(){
System.out.println(a); //a=6
System.out.println(b); //b=3
}
}</span>