目录
1、什么是对象?什么是类?
Java语言中的对象是对现实世界中对象的模拟,Java语言中的对象又称为实例;Java中将现实对象中的信息称为属性(也叫全局变量),将现实对象中的功能称为方法。
Java语言把一组对象中相同属性和方法抽象到一个Java源文件就形成了类。
2、如何定义类,对象的创建和使用:
定义类:
public class 类名 {
//属性
属性1类型 属性1;
属性2类型 属性2;
…
属性n类型 属性n;
//方法
方法1;
方法2;
…
方法m;
}
/*类名的命名规则:
符合标识符命名规范;
类名必须使用英文字母,首字母应大写,如Hello、People等。
当类名由多个”单词”组合而成时,每个单词的首字母都要大写。如 Time、Game、Dog、DateUtil等。
*/
//例如:
public class Student {
//定义属性
String id; //学号
String name; //学生姓名
String grade; //学生年级
//定义读书方法
public void readBook() {
System.out.println(name + “正在读书……");
}
//定义写作业方法
public void doHomework() {
System.out.println(this.name + “正在写作业……");
}
}
对象的创建和使用:
声通过new关键字创建对象。创建对象又称实例化对象。
Student student = new Student();
使用”.”运算符访问对象的属性和方法。
student.属性 = 值;
student.方法名();
public class TestStudent {
public static void main(String[] args) {
Student student = new Student();//创建李四学生类对象
student.id = "wl2014001";
student.name = "李四";
student.grade = "三年级";
student.readBook();//调用学生读书方法
student.doHomework();//调用学生写作业的方法
}
}
类是创建对象的模板,确定对象将会拥有的属性和方法。
类是对象的抽象化;对象是类的具体化。
类是一种数据类型,是对象的数据类型(不同于int等基本类型:类具有方法)
3、方法与重载:
方法:
方法用于定义类的某种行为
访问控制符 [修饰符] 返回值类型 方法名( [参数] ) {
//方法体
}
//例如
public void sayHello(){
System.out.println("Hello");
}
protected final void show(int x){
System.out.println(x);
}
private static int add(int x, int y){
return x+y;
}
访问控制符:方法中的访问控制符用于限制方法在其他类中的使用范围;访问控制符分为四种:public、protected、默认的和private。
修饰符:常用的有static,final,synchronized
1、static修饰的方法可以直接使用类名调用也可以使用类创建的对象调用;
2、非static修饰的方法只能使用类创建的对象调用。
返回值类型:
如果方法没有返回值,需要用void表示。
void sayHello(){
System.out.println("Hello");
}
方法返回基本数据类型的数据,则返回值类型必须是返回数据所属的数据类型或者精度更高的数据类型(针对于数值类型的数据)。
boolean compare(int x, int y){
return x>y;
}
int add(int x, int y){
return x+y;
}
double subtraction(int x, int y){
return x-y;
}
方法返回引用数据类型的数据,则返回值类型必须是返回数据所属的数据类型或者其父类。方法如果有返回值,则必须借助return关键字将数据返回;
public Object getInfo(String name, String address) {
return name + "-" + address;
}
//object是所有类的父类,在这里Object是返回值类型String的父类
方法名:遵循标识符命名规则;首字母必须小写,如果由多个单词组成,从第二个单词开始首字母必须大写;方法名一般由一个动词或者动名词构成。
参数:1、方法可以有多个参数,各个参数之间用逗号间隔。2、方法的参数在整个方法内有效。3、方法参数前面的数据类型用于限制调用方法时所传具体数据的数据类型;
int multiplication(int x, int y){
int result = x*y;
return result;
}
动态参数:1、动态参数实质为数组;2、动态参数必须位于参数列表的最后;3、一个方法只能有一个动态参数;
public static void print(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}
方法递归:方法递归是指一个方法在它的方法体内调用它自身。1、在递归调用中,主调方法同时也是被调方法;2、递归的关键是有结束递归的时机;
static long factorial(int n) {
if(n == 1) {//判断条件,一旦满足就不再递归,逐层返回
return 1;
}else{
return n*factorial(n - 1);
}
}
public static void main(String[] args) {
System.out.println(factorial(5));
}
注意:1、多个方法不能相互嵌套定义!2、方法的返回类型为void,方法中不能有return返回值!3、方法不能返回多个值!4、不能在方法外部直接写程序逻辑代码!
重载:
定义:同一个类中有多个方法名相同但参数列表不同的方法,这种现象称为方法重载(overload)。
其中参数列表不同包括以下情形:
1、参数的个数不同
2、参数的对应类型不同
注意:
1、参数列表不同并不包含参数名不同,也就是说如果方法名相同,方法中参数个数和类型相同,只是参数名不同,这样也不能称之为方法重载。
2、方法中其它构成部分不参与比较:访问控制符、修饰符、返回值类型。
public static void print(int age, String name) {
System.out.println(age + "," + name);
}
public static void print(String name, int age) {
System.out.println(name + "," + age);
}
4、代码块:
Java中代码块分为静态代码块和非静态代码块:
静态代码块只在类加载时执行一次;
public class Test {
static{
System.out.println("静态代码块");
}
public static void main(String[] args) {
}
}
非静态代码块每次创建对象时都会执行;
public class Test {
{
System.out.println("非静态代码块");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
public class Test {
{
System.out.println("非静态代码块");
}
static{
System.out.println("静态代码块");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
//输出结果
//静态代码块
//非静态代码块
//非静态代码块
5、全局变量和局部变量:
成员变量:
直接在类中声明的变量叫成员变量又称全局变量,包括实例属性和类属性。(static修饰)
如果未对成员变量设置初始值,则系统会根据成员变量的类型自动分配初始值:int分配初始值0、boolean分配初始值false,而自定义类型则分配初始值null。
public class Field {
static int v;// 定义int类型数据
static double w;// 定义double类型数据
static char x;// 定义char类型数据
static boolean y;// 定义boolean类型数据
static String z;// 定义String类型数据
public static void main(String[] args) {
System.out.println(v); // 输出0
System.out.println(w); // 输出0.0
System.out.println(x); // 输出空,实质上此时x的值为0
System.out.println(y); // 输出false
System.out.println(z); // 输出null
}
}
成员变量定义后,其作用域是其所在的整个类。成员变量的定义没有先后顺序,但是最好将成员变量的定义集中在类的顶部。
public class Field {
static int x = 10;// 定义int类型
public static void main(String[] args) {
System.out.println(x); // 输出10
System.out.println(flag); // 输出true
}
static boolean flag = true;// 定义boolean类型数据
}
局部变量:
方法中定义的变量和代码块中定义的变量统称为局部变量。包括形参(定义方法括号中的参数),方法局部变量(方法中定义的变量),代码块局部变量(在代码块中定义的变量)。
方法中的参数、局部变量的作用域范围从定义的位置开始到其所在语句块结束。
public class LocalVariable {
{
int x = 9;// 代码块中的局部变量
System.out.println("x=" + x);
}
static void show(int arg) {// 方法参数中的局部变量
if (arg == 1) {
int y = 2;// 方法中的局部变量
System.out.println("y=" + y);
}
// System.out.println(y);//此处不能使用y局部变量
System.out.println("arg=" + arg);
}
public static void main(String[] args) {
new LocalVariable();// 用于执行代码块中的代码
show(1);
}
}
如果局部变量的名字与全局变量的名字相同,则全局变量被隐藏,即这个全局变量在同名局部变量所在方法内暂时失效。如果在局部变量的作用域范围内访问该成员变量,则必须使用关键字this来引用成员变量。
public class LocalVariable {
int x = 1;// 定义一个int类型的全局变量
void show() {
int x = 2;// 方法中的局部变量
System.out.println("x=" + x);// 输出2
System.out.println("x=" + this.x);// 输出1
}
public static void main(final String[] args) {
new LocalVariable().show();
}
}
局部变量在使用以前必须显式初始化或赋值,局部变量没有默认值。
public class LocalVariable {
static void show(int x) {
System.out.println(x);// 不会报错,因为show方法在调用时一定会入一个具体的值。
int y;// 方法中的局部变量
// System.out.println("y="+y);//程序在编译时报错
y = 2;// 赋值
System.out.println("y=" + y);// 输出2
}
public static void main(String[] args) {
show(1);
}
}
声明局部变量时,数据类型前除final外不允许有其他关键字,即其定义格式为: [final] 数据类型 变量名 = 初始值;
public class LocalVariable {
public static void main(String[] args) {
int y = 2;// 在int前面添加public、static都会出错
System.out.println("y=" + y);// 输出2
}
}
关键字static:
static修饰的成员变量称为类属性(又称静态变量):类成员变量的值在所有对象之间共享; JVM加载类时初始化值;可以由所在类创建的对象或类名来调用,推荐使用类名直接调用;没有static修饰的成员变量称为实例属性(又称非静态变量):变量值只属于单个对象;JVM执行创建对象代码时初始化值;只能使用对象来调用。
public class Child {
static int cakeQuantity = 4;// 蛋糕数量
public static void main(String[] args) {
Child liming = new Child();
System.out.println(liming.cakeQuantity);// 输出4
Child xiaoqiang = new Child();
xiaoqiang.cakeQuantity = 3;
System.out.println(liming.cakeQuantity);// 输出3
}
}
方法:
static修饰的方法称为类方法(又称静态方法):此种方法被所有该类的对象共享; JVM加载类时为其分配入口地址;可以由所在类创建的对象或类名来调用,推荐使用类名直接调用;
没有static修饰的方法称为实例方法(又称非静态方法):此种方法对所有该类的对象都是独立的; JVM执行创建对象代码时为其分配入口地址并且只分配一次;只能使用对象来调用;
代码块:
static修饰的代码块称为静态代码块:JVM加载类时该类型代码块执行并且只执行一次;
没有static修饰的代码块称为非静态代码块:JVM执行创建对象代码时执行并且每创建一个对象执行一次;
注意:
静态方法不能直接调用非静态方法,可以间接通过创建该方法(指非静态方法)所在类的对象来调用;非静态方法可以直接调用静态方法;
静态代码块不能直接调用非静态方法;可以间接通过创建该方法(指非静态方法)所在类的对象来调用;静态代码块可以直接调用静态方法;
静态方法或者静态代码块不能直接使用非静态成员变量,可以间接通过创建该成员变量的对象来调用;静态方法或者静态代码块只能直接使用静态变量;
6、构造方法:
构造方法负责初始化类中的实例变量(非“类变量”)构造方法是一种特殊的方法,这种方法必须满足以下语法规则:构造方法必须与类名相同;不包含返回值类型描述部分。构造方法不能有static和final关键字修饰。使用new关键字调用构造方法。
public class TeacherTest {
public static void main(String[ ] args) {
Teacher teacher = new Teacher(); //创建Teacher对象
}
}
//由于Teacher类没有显式构造方法,这时Teacher类就会有一个默认的无参构造方法。
创建类时,如果没有显式定义构造方法,该类就会存在一个默认的无参构造方法。可以在类中声明一个或多个有参构造方法,但每个构造方法在参数个数或参数数据类型上要有所差别;
public class Teacher{
int age;
String name;
public Teacher(String name){
this.name=name;
}
public Teacher(int age){
this.age=age;
}
public Teacher(String name, int age){
this.name=name;
this.age=age;
}
}
如果类中存在显式构造方法,则默认的无参构造方法将不复存在,除非显式定义无参构造方法;
public class Teacher{
int age;
String name;
public Teacher(String name){
this.name=name;
}
public Teacher(String name, int age){
this.(name);
this.age=age;
}
}
类中可以有多个构造方法,构造方法之间可以通过this实现调用,但必须将调用构造函数代码写在有效代码的第一行;
普通方法不能使用this调用类中构造方法
public class Teacher{
int age;
String name;
public Teacher(String name){
this.name=name;
}
public void print(String name){
this(name);
}
}
this代表对当前对象的一个引用;this关键字用于调用属性、方法及本类中构造方法
public class Student {
public void print() {
System.out.println(this);
}
public void main(String [] args){
Student student = new Student();
System.err.println(student);
student.print();
}
}
public class Student {
String name; //学生姓名
public void doHomework() {
System.out.println(this.name + “正在写作业……");
}
}
对象初始化过程:用new创建并初始化对象步骤:
给对象的实例变量(非“常量”)分配内存空间,默认初始化成员变量;
成员变量声明时的初始化;
初始化块初始化(又称为构造代码块或非静态代码块);
构造方法初始化;
public class Student{
String name="张三";
//执行非静态代码块时,对象已经创建,否则this.name会出现错误
{
System.out.println("非静态代码块"+this.name);
}
//调用构造函数时,已经存在了,否则this.name会出现错误
public Student(String name){
this.name = name;
System.out.println("构造方法"+name);
}
//先调用非静态代码块还是先调用构造方法?
public static void main(String[] args) {
Student student = new Student("李四");
}
}
//程序运行结果先输出张三,然后输出李四,可见一定先调用非静态代码块,再调用构造函数,并且调用非静态代码块时所创建对象的实例属性值为初始化值,或者是默认值(如果没有初始化)