面向对象

将功能封装进对象,强调具备了功能的对象,以类或对象为最小单位,考虑谁来做。

面向对象的三大特征:封装、继承、多态


就是对一类事物的描述,是抽象出来的。对象就是实例,是实际存在的该类事物的每个个体。一个类中可以包括:属性、构造器、方法、代码块、内部类。

比如我们把汽车定义为一个类。汽车包括各种类型,如越野车、SUV、轿车等,那SUV就可以是我们创建的对象,它属于汽车这个类。一辆汽车的指标有驱动方式(两驱或者四驱)、排量等等,这些都是“汽车”这个类的属性。我们创建的每个对象都会包含这些属性。汽车可以前进,可以倒车,这些“行动”就是汽车类的方法。

属性 = 成员变量 = field = 域、字段
方法 = 成员方法 = 函数 = method
创建类的对象 = 类的实例化

类的实例化:类名 对象 = new 类名();
例:假设有一个Person类包含三个属性和三个方法

class Person{
	
	//属性
	String name;
	int age;
	boolean isMale;
	
	//方法
	public void eat(){
		System.out.println("吃饭");
	}
	
	public void sleep(){
		System.out.println("睡觉");
	}
	
	public void talk(String language){
		System.out.println("说话:" + language);
	}
	
}

在main函数中可以实例化这个类并能够用别称调用该类的属性和方法:

Person p1 = new Person();
//调用属性:“对象.属性”
p1.name = "Tom";
p1.isMale = true;
System.out.println(p1.name);

//调用方法:“对象.方法”
p1.eat();
p1.sleep();
p1.talk("Chinese");

类和对象的创建和执行操作有三步:
1.创建类
2.类的实例化
3.调用对象的结构:属性和方法

注:如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)


属性(成员变量)与局部变量辨析:

相同点:定义变量的格式是相同的

格式:数据类型 变量名 = 变量值
都需要先声明,后使用。都有其对应的作用域

不同点:

1.在类中声明的位置的不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量

2.关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符。
常用的权限修饰符:private、public、缺省、protected
在定义时不使用权限修饰符则
局部变量:不可以使用权限修饰符。

3.默认初始化值的情况:
属性:类的属性,根据其类型,都有默认初始化值。
整型(byte、short、int、long):0
浮点型(float、double):0.0
字符型(char):0 (或’\u0000’)
布尔型(boolean):false
引用数据类型(类、数组、接口):null
局部变量:没有默认初始化值,即在调用局部变量之前,一定要显式赋值。
特别地:形参在调用时,我们赋值即可。

4.在内存中加载的位置:
属性:加载到堆空间中 (非static)
局部变量:加载到栈空间

定义方法可以有形参也可以没有形参。有形参在调用的时候就需要传值。方法可以通过对象名调用。


如何在当前文件类里调用其他java文件中的类,例:

(1)创建Person类的对象,设置该对象的name、age和sex属性,调用study方法,
输出字符串“studying”,调用showAge()方法显示age值,
调用addAge()方法给对象的age属性值增加2岁。
(2)创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系。

Person类:

public class Person {
    String name;
    int age;
    //  1 表明是男性0 表明是女性

    int sex;

    public void study(){
        System.out.println("studying");
    }

    public void showAge(){
        System.out.println("age:" + age);
    }

    public int addAge(int i){
        age += i;
        return age;
    }
}

PersonText类:

public class PersonText {
    public static void main(String[] args) {
        Person p1 = new Person();

        p1.name = "Lorito";
        p1.age = 20;
        p1.sex = 0;

        p1.study();
        p1.showAge();

        int newAge = p1.addAge(2);
        System.out.println(p1.name + "的新年龄为:" + newAge);

        System.out.println(p1.age);

        Person p2 = new Person();
        p2.showAge(); //结果为0 因为是新建的对象且没有赋值
        p2.addAge(10);
        p2.showAge(); //10
        p1.showAge();

    }
}

用哪个对象去调用addAge就在哪个对象的age属性基础上进行加10,每个对象的值都是独立的。


对象数组练习:

定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。(年级为[1,6])
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息

提示:1) 生成随机数:Math.random(),返回值类型double;
2) 四舍五入取整:Math.round(double d),返回值类型long。

在此题目中new20个学生对象是不现实的,因此要考虑对象数组。新建了长度为20的对象数组后,要先给每一个位置new一个对象用于存放student属性,最后再给每一个对象的属性赋值。对象数组的每一个位置存放的是一个student对象,每一个对象内又包含三个属性和一个方法。另外在冒泡排序交换时,不能交换成绩,要连同对象交换。假如A同学的成绩是a,B同学的成绩是b,如果只交换成绩就会变成A同学的成绩是b,B同学的成绩是a。

public class ObjectArrayText{
    static class Student{
        int number;
        int state;
        int score;
        public String info(){
            return "学号:" + number + ",年级:" + state + ",成绩:" + score;
        }

    }
    public static void main(String[] args) {
        Student[] student = new Student[20];
        for (int i = 0; i < 20; i++){
            student[i] = new Student();
            student[i].number = i + 1;
            student[i].state = (int)(Math.random() * 6 + 1);
            student[i].score = (int)(Math.random() * 101);
        }
        for (int j = 0;j < 20; j++) {
            //if (student[j].state == 3)
                System.out.println(student[j].info());
        }
        Sort(student);
    }

    public static void Sort(Student[] st){//只排序成绩
        for(int i = 0;i < st.length - 1;i++){
            for(int j = 0;j < st.length - 1 - i;j++){
                if(st[j].score > st[j + 1].score){
                    //如果需要换序,交换的是数组的元素:Student对象!!!
                    Student temp = st[j];
                    st[j] = st[j + 1];
                    st[j + 1] = temp;
                }
            }
        }
        System.out.println("排序结果如下:");
        for (int k = 0 ; k < 20; k++){
            System.out.println(st[k].info());
        }
    }
}

JVM内存结构

类加载到内存中是在程序运行时开始,即对编译完源程序生成的字节码文件进行解释运行。

程序中的局部变量存储在虚拟机栈中,而new出来的对象、数组等加载在堆控件中。非static的对象的属性也加载在堆空间中。