Java基础教程-面向对象(上)

294 阅读4分钟

image.png

image.png

面向过程与面向对象

image.png

image.png

image.png

image.png image.png

image.png

Java基本元素:类、对象

image.png

类是抽象,类实例化后就是对象(又叫实例)。

image.png

image.png

image.png

image.png

image.png

对象的创建与使用

image.png

创建类的对象 = 类的实例化 = 实例化类

image.png

public class PersonTest {
    public static void main(String[] args) {
        // 2. 创建类对象
        Person p1 = new Person();
        // 3. 调用对象的方法和属性
        p1.name="tony";
        p1.age=48;
        p1.eat();
        p1.speak("Chinese");

        Person p2 = new Person();
        System.out.println(p2.name); //null

    }
}
// 1. 创建类,设计类的成员
class Person{
    // 属性
    String name;
    int age=1;
    // 方法
    public void eat(){
        System.out.println("人喜欢吃猫肉");
    }

    public void speak(String language){
        System.out.println("人可以说"+language);

    }

}

内存解析

image.png

对象的内存解析 image.png

类的成员之一:属性

image.png

image.png

image.png

类的成员之二:方法

image.png

image.png image.png

image.png image.png

image.png

对象数组

image.png Student.java

public class Student {

    int number;
    int state;
    int score;

}

StudentTest.java

public class StudentTest {
    public static void main(String[] args) {
        // 声明Student类型的数组
        Student[] stus =new Student[20];
        // 给元素赋值
        for (int i=0;i<20;i++) {
            stus[i] = new Student();
            // 给Student对象赋值
            stus[i].number = i + 1;
            stus[i].state = (int) (Math.random() * 6 + 1);
            stus[i].score = (int) (Math.random() * 90 + 10);
            System.out.println("原始学生信息,学号:" + stus[i].number + ",年级:" + stus[i].state + ",成绩:" + stus[i].score);

        }
        //学生排序
        for (int i=0;i<stus.length;i++){
            for (int j=0;j<stus.length-i-1;j++){
                if (stus[j].score>stus[j+1].score){
                    //如果需要换序,交换的是数组的元素:Student对象
                    Student temp = stus[j];
                    stus[j] = stus[j+1] ;
                    stus[j+1]= temp;
                }
        }
        }
        System.out.println("----------");
        for (int i=0;i<20;i++) {
            System.out.println("排序后的学生信息,学号:" + stus[i].number + ",年级:" + stus[i].state + ",成绩:" + stus[i].score);
        }
        
        }
        
    }

对象数组内存解析 image.png

JVM内存结构

image.png

理解万事万物皆对象

image.png

对象数组的内存解析

image.png

匿名对象

image.png

public class InstanceTest {
    public static void main(String[] args) {
        // 有名的对象 有名,p
        Phone p = new Phone();
        System.out.println(p);
        p.sendEmail();
        p.playGame();
        p.showPrice();
        // 匿名对象
        // 每new一次是不同的一个对象
        new Phone().price=1999;
        new Phone().showPrice();// 0.0
        // 匿名对象在开发中的使用
        PhoneMall mall = new PhoneMall();
        // 给phone赋值了:new Phone()
        mall.show(new Phone());

    }
}

class PhoneMall{
    public void show(Phone phone){
        phone.sendEmail();
        phone.playGame();
    }
}

class Phone{
    double price;//价格
    public void sendEmail(){
        System.out.println("发送邮件");
    }
    public void playGame(){
        System.out.println("打游戏");
    }
    public void showPrice(){
        System.out.println("手机价格为:"+price);
    }

}

自定义数组工具类

ArraysUtil.java

package com.company.day09;

public class ArraysUtil {

    // 数组最大值
    public int getMax(int[] arr){
        int max = arr[0];
        for (int i=1;i<arr.length;i++){
            if (arr[i]>max){
                max = arr[i];
            }
        }
        return max;
    }

    // 数组最小值
    public int getMin(int[] arr){
        int min = arr[0];
        for (int i=1;i<arr.length;i++){
            if (arr[i]<min){
                min = arr[i];
            }
        }
        return min;
    }

    // 数组元素总和
    public int getSum(int[] arr){
        int sum=0;
        for (int i=0;i<arr.length;i++){
            sum=sum+arr[i];
        }
        return sum;
    }

    // 数组的平均值
    public double getAvg(int[] arr){
        double avg = getSum(arr)/(arr.length/1.0);
        return avg;
    }

    // 反转数组
    public int[] getRevArr(int[] arr){
        for(int i=0;i<arr.length/2;i++){
            int temp=arr[i];
            arr[i]=arr[arr.length-i-1];
            arr[arr.length-i-1]=temp;
        }
        return arr;
    }

    // 复制数组
    public int[] copyArr(int[] arr){
        int[] newArr = new int[arr.length];
        for (int i=0;i<arr.length;i++){
            newArr[i]=arr[i];
        }
        return newArr;
    }

    // 数组排序
    public int[] sortArr(int[] arr){
        for (int i=0;i<arr.length;i++){
            for (int j=0;j<arr.length-1-i;j++){
                if (arr[j]>arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        return arr;
    }
    // 查找制定元素
    public int search(int[] arr,int target) {
        int index = -1;//标识是否找到,未找到为-1;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) {
                index = i;

            }
        }
        return index;
    }

}

ArraysUtilTest.java

package com.company.day09;

import java.util.Arrays;

public class ArraysUtilTest {
    public static void main(String[] args) {
        ArraysUtil util =new ArraysUtil();
        int[] arr = new int[]{1,2,9,4,12,6};
        int max=  util.getMax(arr);
        int min=  util.getMin(arr);
        int sum= util.getSum(arr);
        double avg= util.getAvg(arr);
        // 反转数组
        int arr1[]= util.getRevArr(arr);
        // 复制数组
        int arr2[] = util.copyArr(arr);
        // 数组排序
        int arr3[] = util.sortArr(arr);
        // 搜索元素
        int index = util.search(arr,12);
        System.out.println(max);
        System.out.println(min);
        System.out.println(sum);
        System.out.println(avg);
        System.out.println(Arrays.toString(arr1));
        System.out.println(Arrays.toString(arr2));
        System.out.println(Arrays.toString(arr3));
        System.out.println(index);
    }

}

再谈方法

  1. 方法的重载

image.png

image.png

练习:

image.png

public class OverloadTest {

    public static void main(String[] args) {
        OverloadTest ovl =  new OverloadTest();
        System.out.println(ovl.compute(3));
        System.out.println(ovl.compute(3,10));
        ovl.compute("重载好像不难");

        System.out.println(ovl.getMax(3,9));
        System.out.println(ovl.getMax(3.1,3.2));
        System.out.println(ovl.getMax(9.9,12.1,17.5));

    }

    public int compute(int num){
        return num*num;
    }
    public int compute(int num1,int num2){
        return num1*num2;
    }
    public void compute(String str){
        System.out.println(str);
    }


    public int getMax(int num1, int num2){
        return (num1>num2?num1:num2);
    }

    public double getMax(double num1, double num2){
        return (num1>num2?num1:num2);
    }
    public double getMax(double num1, double num2,double num3){
        return (num3>(num1>num2?num1:num2))?num3:(num1>num2?num1:num2);
    }


}
  1. 可变形参的方法

image.png

image.png

  1. 方法参数的值传递机制(重点)

image.png

image.png

main方法调用的sout(m,n)和swap方法调用的sout(m,n)不一样。swap方法调用完之后,就会销毁掉m,n,temp。

image.png

image.png

import java.util.Arrays;

public class ExeTest {
    public static void main(String[] args) {
        int[] arr = new int[]{12,3,3,34,56,77,432};
        int[] arr1 = new int[arr.length];
        for (int i=0;i<arr.length;i++){
            arr1[i] = arr[i]/arr[0];
        }
        System.out.println(Arrays.toString(arr1));
    }
    
}
  1. 递归方法

image.png

OPP特征之一:封装与隐藏

image.png

  1. 封装性的体现
public class AnimalTest {
    public static void main(String[] args) {
        Animal an =new Animal();
        an.age=10;
        an.legs=-4;
        an.show();

    }

}
class Animal{
    int age ;
    String name;
    int legs;
    public void show(){
        System.out.println("动物的年纪:"+age+",动物的脚:"+legs);//动物的年纪:10,动物的脚:-4
    }
}

可以随意修改legs的数字,只能限定为int型,但实际legs应为正整数。

给legs声明为私有变量,提供一个方法setLegs()去修改legs,方法中增加对这个变量的限制条件。除了修改属性的值,还需要提供getLegs()获取到属性的值。

public class AnimalTest {
    public static void main(String[] args) {
        Animal an =new Animal();
        an.age=10;
//      an.legs=-4; 不能直接使用 an.legs调用了。需要调用setLegs方法
//      an.setLegs(-4); 应该会报错,但是还没学。
        an.setLegs(4);
        int legs = an.getLegs();
        System.out.println(legs);
        an.show();

    }

}
class Animal{
    int age ;
    String name;
    private int legs;//给属性legs声明为私有权限,使legs对外不可见。
    //  要修改legs,需要调用setLegs。方法中添加对legs修改时的限制条件
    public void setLegs(int l){
        if (l>0&&l%2==0){
            legs=l;
        }else {
            legs=0;//标记错误
            System.out.println("抛出异常,还没学");
            System.out.println("legs错误");
        }

    }
    // 可以修改,也要可以获取,要获取legs,调用getLegs获取
    public int getLegs(){
        return legs;
    }
    public void show(){
        System.out.println("动物的年纪:"+age+",动物的脚:"+legs);//动物的年纪:10,动物的脚:-4
    }
}

封装性的体现就是将类的属性私有化,同时提供公共(public)的setXXX来设置属性,提供公共(public)的getXXX方法来获取属性。set是没有返回值的,get是有返回值的。

  1. 权限修饰符

image.png

image.png

image.png

类的成员之三:构造器(或构造方法、constructor)

image.png

  1. 构造器的作用

    创建对象、给对象进行初始化。

  2. 构造器说明

image.png

public class PersonTest {
    public static void main(String[] args) {
        // 创建类的对象
        // 变量类型 变量名 = new 一个对象 -->Person()就是构造器
        // 构造器与类同名
        Person p = new Person();
        p.eat();
        // 使用有参数的构造器创建对象
        Person p1 = new Person("tom");
        // 构造器对name进行了初始化
        System.out.println(p1.name);//tom
    }

}

class Person{
    // 属性
    String name;
    int age;

    // 构造器 默认的构造器是这样,不用写
    public Person(){
        System.out.println("这是构造器");
    }

    // 有参数的构造器
    public Person(String n){
        name = n;

    }

    // 方法
    public void eat(){
        System.out.println("人吃饭");
    }
}

构造器与方法是不同的,需要先用构造器创建对象,再去调方法。

image.png

public class PersonTest {
    public static void main(String[] args) {
        Person p=new Person(23,"tom");
        System.out.println(p.age);
        System.out.println(p.name);

    }

}

class Person{
    int age;
    String name;
    public Person(String n){
       age =18;
       name =n;
   }
}

image.png

TriAngle.java

public class TriAngle {

    private int base;
    private int height;

    // 构造器
    // 一般习惯性会提供一个空参构造器
    public TriAngle(){
        
    }
    public TriAngle(int b,int h){
        base =b;
        height=h;

    }


    public void setBase(int b){
        if (b>0){
            base =b;
        }else {
            System.out.println("参数非法");
        }
    }
    public int getBase(){
        return base;
    }

    public void setHeight(int h){
        if (h>0){
            height=h;
        } else {
            System.out.println("参数非法");
        }
    }

    public int getHeight(){
        return height;
    }

    public int triangleArea(){
        return (base*height)/2;
    }
}

TriAngleTest.java

public class TriAngleTest {
    public static void main(String[] args) {
        TriAngle tra = new TriAngle(12,20);
        System.out.println(tra.triangleArea());
        tra.setBase(15);
        tra.setHeight(20);
        System.out.println(tra.triangleArea());

    }
}

image.png

  1. JavaBean (拓展)

image.png

  1. UML类图(拓展)

image.png

关键字:this

image.png

image.png image.png

public class TriAngle {

    private int base;
    private int height;

    // 构造器
    // 一般习惯性会提供一个空参构造器
    public TriAngle(){

    }
    public TriAngle(int base){
        this.base=base ;
        System.out.println("假装有40行代码");

    }
    public TriAngle(int base,int height){
        // 假装需要TriAngle(int base)中的40行代码,可以使用this()调用
        this(base);
        // 变量名需要望文生义,所以形参如果不使用this,不能区分谁是类的属性,谁是参数
        this.height=height;

    }

    public void setBase(int base){
        if (base>0){
            this.base =base;
        }else {
            System.out.println("参数非法");
        }
    }
    public int getBase(){
        return base;
    }

    public void setHeight(int height){
        if (height>0){
            this.height=height;
        } else {
            System.out.println("参数非法");
        }
    }

    public int getHeight(){
        return height;
    }

    public int triangleArea(){
        return (base*height)/2;
    }
}

给私有属性快速生成get\set方法的技巧:

光标放在私有属性上,ctrl+enter呼出generate选项,选择Getter and Setter:

image.png

选择Constructor是自动生成构造器,可以选择是否带参数。

关键字package、import

  1. package image.png

image.png

  1. MVC设计模式(拓展)

image.png

image.png

  1. import

image.png

image.png

image.png

image.png