IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 面向对象的学习 -> 正文阅读

[Java知识库]面向对象的学习

面向对象(上)

Java面向对象学习的三条主线

  1. java类及类的成员:**属性、方法、构造器;**代码块、内部类
  2. **面向对象的三大特征:**封装、继承、多态
  3. 其他关键字:this、super、static、final、abstract、interface、package、import

面向对象与面向过程

面向过程(POP)与面向对象(OOP)

  1. 面向过程:强调的是功能、以函数为最小单位,考虑怎么做

  2. 面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做

面向对象的思维概述:

  • 程序员从面相过程的执行着转化成了面向对象的指挥者
  • 面向对象分析方法分析问题的思路和步骤:
    1. 根据问题需要,选择问题所针对的现实世界中的实体。
    2. 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
    3. 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即接著某种程序语言,把类构造成计算机能够识别和处理的数据结构。
    4. 将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。

Java语言中的基本元素:类和对象

  • 类和(Class)和对象(Object)是面向对象的和性概念

    • 类是对一类事物的描述,是抽象的、概念上的定义

    • 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)

  • 万事万物皆对象

  • 比如人、猪、狗、玩具、水果,对某一类实物的抽象

  • 面向对象程序设计的重点是对类的设计

  • 类的设计,就是设计类的成员

    • 现实世界中的生物体,达到鲸鱼,小到蚂蚁,都是有最基本的细胞构成的。同理,Java代码世界是由诸多个不同功能的类构成的。
    • 类中的两个主要的成员:属性和方法
  • 属性=成员变量=field=域、字段

  • 方法=成员方法=函数=method

类和对象的创建与使用

  1. 创建类,设计类的成员
  2. 创建类的对象
  3. 通过“对象.属性”或“对象.方法”调用对象的结构
public class Mini {
    public static void main(String[] args) {
        //实例化对象
        Person p1 = new Person();
        p1.name = "小狗蛋";
        p1.sex = '女';
        p1.age = 24;
        p1.height = 158;
        p1.eat();
        p1.sleep();
        p1.talk("中文");
    }
    }
class Person {
    //属性:名字、性别、身高
    String name;
    int age;
    char sex;
    double height;
    //方法:睡觉、吃法、说话
    public void eat(){
        System.out.println("人会吃饭");
    }
    public void sleep(){
        System.out.println("人要睡觉");
    }
    public void talk(String language){
        System.out.println("中国人说的是"+language);
    }
}

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

? 也就是说,我们修改了一个对象的属性,并不会影响另一个对象的属性

对象的内存解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TOGaTTUu-1644334828455)(C:\Users\lin\AppData\Roaming\Typora\typora-user-images\image-20220111212301417.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5LeUIsv-1644334828456)(C:\Users\lin\AppData\Roaming\Typora\typora-user-images\image-20220111213339194.png)]

属性(成员变量)与局部变量的对比

  1. 相同点

    1. 定义变量的格式相同:数据类型 变量名 = 变量值;
    2. 先声明,后使用
    3. 变量都有其对应的作用域
  2. 不同点

    1. 定义的位置不同:
      • 成员变量:直接定义在类中的变量,在类的大括号{}里面
      • 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
    2. 关于权限修饰符的不同:
      • 属性可以在声明属性时,使用权限修饰符指明其权限。
      • 常用的权限修饰符:public、private、protected 、缺省(未声明权限修饰符)–>封装性
      • 局部变量不能使用权限修饰符,他的权限与方法的权限一致。
    3. 默认初始化值的情况:
      • 属性:类的属性,根据其基本类型,都有默认初始化值。
        • 整形(byte、short、int、long):0
        • 浮点型(float、double):0.0
        • 字符型(char):0或\u0000
        • 引用数据类型(类、数组、接口):null
      • 局部变量:没有默认初始化值
        • 意味着我们在调用局部变量时必须先赋值public (public static void main(String[] args) { //这里面的args(形式参数)也是局部变量)
        • 形式参数我们在调用时再赋值即可
    4. 在内存中加载的位置不同
      1. 属性:加载到堆空间中(非static)
      2. 局部变量:加载到栈中

方法的举例和声明的格式

类中方法的声明和使用

  • 方法:描述该类具有的功能
  • 比如:
    • Math类:sqrt()\random()…
    • Scanner类:nextXxx()…
    • Arrays类:sort()\binarySearch()\toString()\equals()…
public class Text {

    public static void main(String[] args) {

    }
    class Customer{
        //属性
        String name;
        int age;
        boolean married;
        //方法的声明:权限修饰符 返回值 方法名(形式参数列表){方法体}
        public void eat(String food){
            System.out.println("客户去吃饭了,吃的是"+food);
        }
        public void sleep(){
            System.out.println("客户现在在休息");
        }
        public String getName(){
            return name;
        }
        public String getNation(String nation){
            String info ="我的国籍是:"+ nation;
            return info;
        }
    }
}

方法声明的说明

  1. 关于权限修饰符(四个):private、public、缺省、protected–>封装性再细讲
  2. 返回值类型:有返回值 & 没有返回值
    • **如果方法有返回值:**必须在方法声明时指定返回值的类型。同时在方法中需要使用return 指定返回值类型的数据。
    • **没有返回值:**在声明方法时,则需要使用void来表示。农场没有返回值的方法中,不需要使用return。也可以使用“return;”来结束方法,只有结束方法的作用,后面的语句不能执行。
  3. 方法名:属于标识符,需要满足首字母大写,驼峰原则,需要见名知意。
  4. 形参列表:方法可以声明0个、一个或者多个形参
    1. 格式:数据类型1 形参1,数据类型2 形参2,…
    2. 我们定义方法时,是否需要定义形参:视情况而定
  5. 方法体:具体方法的实现

return关键字的使用

  1. 使用范围:使用在方法体中
  2. 作用:
    1. 结束方法
    2. 针对有返回值类型的方法, 使用“return 数据”方法返回所要的数据
  3. return关键字后面不能声明语句,这一点和break是一样的

方法的使用

  1. 方法在使用中可以调用当前类的属性及当前类中的方法
    • 可以调用别的方法
    • 也可以调用自己(递归)

利用面向对象的方法,设计Circle类计算园的面积

package OOP.Circle;
//利用面向对象的方法,设计Circle类计算园的面积
public class CircleText {
    public static void main(String[] args) {
        Circle cir = new Circle();
        cir.radius = 3;
//        double area = cir.getArea();
//        System.out.println(area);
        cir.getArea();
    }
}
//方法一
//class Circle{
//        double radius;
//        public double getArea(){
//            double area = Math.PI*radius*radius;
//            return area;
//        }
//
//}
//方法二
class Circle{
    double radius;
    public void getArea(){
        System.out.println("圆的面积为:"+Math.PI*radius*radius);

    }

}

打印自定义矩形

package OOP.Exer;
import java.util.Scanner;
/*
3.1编写程序,声明一个method方法,在方法中打印一个10×8的“*”矩形,在main方法中调用该方法。
3.2修改上面一个程序,除了打印矩形外,再计算该矩形的面积
并将其作为返回值,在main方法中调用该方法,接收返回的面积并打印
3.3修改上一个程序,在method方法提供m和n两个参数,方法中打印一个m×n的矩形,将其作为返回值,在main方法中调用该方法,接收返回的面积并打印
 */
public class RectangleText {
    public static void main(String[] args) {
        Rectangle rect = new Rectangle();
        System.out.println("请输入长度m的值:");
        rect.m = rect.getVal();
        System.out.println("请输入宽度n的值:");
        rect.n = rect.getVal();
        rect.diagramPrint();
        rect.printArea();
    }
}

class Rectangle{
    int m;
    int n;
    //输出面积
    public void printArea(){
        System.out.println("矩形面积为:"+m*n);
    }
    //打印图形
    public void diagramPrint(){
        System.out.println("打印矩形:");
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print("*\t");
            }
            System.out.println();
        }
    }
    //创建一个从键盘接收数据的方法
    public int getVal(){
        int val = 0;
        for (; ; ) {
            Scanner sca = new Scanner(System.in);
            if (sca.hasNextInt()){
                val= sca.nextInt();
                return val;
            }else {
                System.out.println("请输入正确的数据类型!");
            }
        }
    }
}

打印学生信息

package OOP.Student;
    /*定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
创建20个学生对象,学号为1到20,年级和成绩都有随机数确定。
1.打印出3年级(state=3)的学生信息。
2.使用冒泡排序将学生按成绩排序,并遍历所有学生的信息
 */
public class StudentText {
    public static void main(String[] args) {
        Student[] student = new Student[20];//创建一个Student类型的数组
        for (int i = 0; i < student.length; i++) {
            student[i] = new Student();//给数组元素赋值,这个值就是Student类型的值。
            student[i].number = i+1;
            student[i].state = (int) (Math.random()*(6-1+1)+1);
            student[i].score = (int) (Math.random()*(100-0+1)+0);
            //输出三年级学生的信息
            if (student[i].state == 3){
                student[i].info();
            }
        }
        //使用冒泡排序以成绩高低对学生进行排序
        for (int i = 0; i < student.length-1; i++) {
            for (int j = 0; j < student.length-1-i ; j++) {
                if (student[j].score>student[j+1].score){
                Student temp = student[j];
                student[j] = student[j+1];
                student[j+1] = temp;
                }
            }
        }
        //打印所有学生的信息
        for (int i = 0; i < student.length-1; i++) {
            student[i].info();
        }
    }
}
//创建类
class Student{
    int number;//学号
    int state;//年级
    int score;//成绩
    //打印学生信息的方法
    public void info(){
        System.out.println("学号"+number+"\t年级:"+state+"\t成绩:"+score);
    }
}
改进
package OOP.Student;
    /*定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
创建20个学生对象,学号为1到20,年级和成绩都有随机数确定。
1.打印出3年级(state=3)的学生信息。
2.使用冒泡排序将学生按成绩排序,并遍历所有学生的信息
3.改进,将方法封装
 */
public class StudentText {
    public static void main(String[] args) {
        Student[] student = new Student[20];//创建一个Student类型的数组
        for (int i = 0; i < student.length; i++) {
            student[i] = new Student();//给数组元素赋值,这个值就是Student类型的值。
            student[i].number = i+1;
            student[i].state = (int) (Math.random()*(6-1+1)+1);
            student[i].score = (int) (Math.random()*(100-0+1)+0);
        }
        StudentText studentText = new StudentText();
        System.out.println("打印指定年级的学生信息:");
        studentText.searchInfo(student,3);
        studentText.sort(student);//以成绩对学生信息进行排序
        System.out.println("打印排序后的学生信息");
        studentText.arrPrint(student);
    }

        /**
         * @description 查找Student数组中指定年级的学生信息
         * @author 漆林
         * @param stu
         * @param state
         */
    public void searchInfo(Student[] stu,int state){
        for (int i = 0; i < stu.length; i++) {
            if (stu[i].state == state){
                stu[i].info();
            }
        }
    }

        /**
         * @description 使用冒泡排序对Student数组进行排序
         * @author 漆林
         * @param stu
         */
    public void sort(Student[] stu){
        for (int i = 0; i < stu.length-1; i++) {
            for (int j = 0; j < stu.length-1-i ; j++) {
                if (stu[j].score>stu[j+1].score){
                    Student temp = stu[j];
                    stu[j] = stu[j+1];
                    stu[j+1] = temp;
                }
            }
        }
    }
        /**
         * @description 使用冒泡排序对Student数组进行排序
         * @author 漆林
         * @param stu
         */
    public void arrPrint(Student[] stu){
        for (int i = 0; i < stu.length-1; i++) {
            stu[i].info();
        }
    }
}
//创建类
class Student{
    int number;//学号
    int state;//年级
    int score;//成绩
    //打印学生信息的方法
    public void info(){
        System.out.println("学号"+number+"\t年级:"+state+"\t成绩:"+score);
    }
}

面向对象 一 复习

1.面向对象学习的三条主线

  1. 类与类的成员:属性、方法、构造器;代码块、内部类
  2. 面向对象的三大特性:封装、继承、多态
  3. 其它关键字:static、interface、import、package、final、this…

2.面向对象与面向过程(理解)

  1. 面向过程:强调的是工程行为,以函数为最小单位,考虑怎么做
  2. 面向对象:清点具备功能的对象,以类/对象为最小单位,考虑谁来做
  3. 举例:人把大象放冰箱

3.完成一个项目(功能)的思路:

  1. 根据问题的需要,选择问题所针对的现实世界中的实体。
  2. 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
  3. 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
  4. 将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。

4.面向对象中的两个重要的概念

  • 类:对一类事物的描述,是抽象的、概念上的定义
  • 对象:是实际存在的该类事物的每个个体,因而也被称为实例(instance)
  • 面向对象程序设计的重点是类的设计
  • 设计类,就是设计类的成员
  • 类是对象的抽象描述,对象是类的实例化

5.面向对象思想落地的规则一

  1. 创建类,设计类的成员
  2. 实例化类,创建类的对象
  3. 调用类中的属性和方法(“对象.方法”“对象的.属性”)

6.属性(成员变量)和局部变量的异同

  • 相同点:
    • 命名规则规范相同
    • 都是先声明、后使用
    • 变量都具有其对应的作用域
  • 异同:
    • 声明的位置不同:属性是在类中声明的声明的。局部变量是在方法内、内部类、构造器内声明的,形式参数也属于局部变量。
    • 初始化值:属性(成员变量)有初始化值,局部变量没有初始化值(形式参数必须初始化值才能使用)

7.return关键字

  • 适用范围
  • 作用

理解万物皆对象

理解“万事万物皆对象”

  1. 在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
    • Scanner,String
    • 文件:File
    • 网络资源:URL
  2. 涉及到Java语言与前端的Html、后端的数据库交互时,前后端的结构在Java层面交互时,头体现为类、对象。

对象数组的内存解析

  1. 引用类型的变量,只可能存储两类值:null或者地址值(含变量类型)[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zgXsDTX7-1644334828457)(C:\Users\lin\AppData\Roaming\Typora\typora-user-images\image-20220113233156025.png)]

匿名对象的使用

  1. 理解:匿名对象,我们创建对象时间

  2. 匿名对象不能重复使用,因为没有在栈空间中创建地址值,每一次调用都是一个新的对象

  3. 使用如下:

  4. package OOP.Instance;
    public class InstanceText {
        public static void main(String[] args) {
            Phone p = new Phone();
            p.playGame();
            p.sendEmail();
            new Phone().price = 1999;//给匿名对象赋值
            new Phone().showPrice();//此时打印出来的值为0,说明匿名对象只能使用一次
            //匿名对象的使用
            ShowMall mall = new ShowMall();
            mall.show(new Phone());//此时打印出来的price为1996
        }
    }
    class ShowMall{
        /*
        //当把Phone传递过来的时候相当于new了一个Phone,
        这个Phone的名称就叫phone,在调用这个类时,匿名对象可以被多次使用
         */
        public void show(Phone phone){
            /*此时phone在调用这个类真的方法时候使用的就是同一个对象*/
           phone.price = 1996;
           phone.sendEmail();
           phone.readNews();
           phone.readMovies();
           phone.showPrice();
        }
    }
    class Phone{
        int price;
        public void showPrice(){
            System.out.println("此手机价格为:"+price);
        }
        public void sendEmail(){
            System.out.println("发送邮件");
        }
        public void playGame(){
            System.out.println("打游戏");
        }
        public void readNews(){
            System.out.println("看新闻");
        }
        public void readMovies(){
            System.out.println("看电影");
        }
    }
    

工具类的封装

package OOP.ArrayUtil;

class ArrayUtil {
    //求数组最大值
    public int getMax(int[] arr){
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max<arr[i]){
                max = arr[i];
            }
        }
        return max;
    }
    //求数组最小值
    public int getMin(int[] arr){
        int min = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (min>arr[i]){
                min = arr[i];
            }
        }
        return min;
    }
    //求数组和
    public int getSum(int[] arr){
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
        }
        return sum;
    }
    //求数组平均值
    public int getAverage(int[] arr){
            return getSum(arr)/arr.length;
    }
    //反转数组
   public void reversal(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;
       }
   }
    //数组排序
    public void sort(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 y = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = y;
                }
            }
        }
    }
    //复制数组
    public int[] arrCopy(int[] arr){
        int[] name = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            name[i] = arr[i];
        }
        return name;
    }
    //遍历数组
    public void printArr(int[] arr){
        for (int i = 0; i < arr.length-1; i++) {
            System.out.print(arr[i]+"\t");
        }
        System.out.println();
    }
    //查找指定元素,查找地址值
    public int search(int[] arr,int val){
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == val){
                return i;
            }
        }
        return -1;
    }
}

测试封装的工具类

package OOP.ArrayUtil;
public class ArrayUtilText {
    public static void main(String[] args) {
        int[] arr1 = new int[]{3,0,-1,2,99,88,12,-21};
        ArrayUtil util = new ArrayUtil();
        util.sort(arr1);
        util.printArr(arr1);//打印数组
        System.out.println("最大值:"+util.getMax(arr1));
        System.out.println("最小值:"+util.getMin(arr1));
        System.out.println("数组求和:"+util.getSum(arr1));
        util.reversal(arr1);//反转数组
        util.printArr(arr1);
        System.out.println("在数组中找到元素,在数组中的位置为:"+(util.search(arr1,3)+1));
    }
}

再谈方法

方法的重载

  • **重载的概念:**在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可。(两统一不同:同一个类,同一个方法名称,参数列表不同)

  • **重载的特点:**与返回值类型无关,只看参数列表,且参数列表必须不同(参数个数或者参数类型)。调用时,根据方法参数列表的不同来区别。

  • 重载示例

    • 返回两个整数的和:int add(int x, int y){return x+y;}

    • 返回三个整数的和:int add(int x, int y,int z){return x+y+z;}

    • 返回两个小数的和:double add(double x, double y){return x+y;}

    • package OOP.OverLoadText;
      class OverLoadUtil {
          //如下的四个方法就构成了重载
          public void sum (int a,int b){
              System.out.println(a+b);
          }
          public void sum (int a,double b){
              System.out.println(a+b);
          }
          public void sum (double b,int a){
              System.out.println(a+b);
          }
          public double sum (double b,int a,int c){
              System.out.println(a+b);
              return a + b + c;
          }
      }
      
      
  • 在调用重载的方法时,如果确定调用的是哪一个方法:

    • 先通过方法名–>再查看参数列表

可变形参数

  1. 可变形参数是jdk5.0的新特性
  2. 具体使用:
    1. 可变个数形参格式:数据类型…变量名
    2. 当调用可变个数形参的方法是,传入的参数个数可以是0个、一个或者多个
    3. 可变个数形参的方法与本类中方法名相同,形参不同的方法直接构成重载
    4. 可变个数形参的方法与本类中方法名相同,形参类型相同的数组之间不构成重载(不能共存)。其实与数组的参数是一样的
    5. 可变形参数必须声明在参数列表的末尾,也就是只能声明一个可变型参数

方法参数的值传递机制**

基本数据类型传递

  • 方法必须由其所在类或对象调用才有意义。若方法含有参数

    • 形参:方法声明时的参数

    • 实参:方法调用时实际传给形参的参数值

  • Java的实参值如何传递给方法呢?

    • Java里方法的参数传地方是只有一种:值传递。即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响
      • 形参是基本数据类型时:将实参基本数据类型变量的“数据值”传递给形参
      • 形参时引用数据类型时:将实参引用数据类型变量的“地址值”传递给形参,改变形参的值时,实参的值也会被改变
package OOP.ValueTransferText;
public class ValueTransferText {
    public static void main(String[] args) {
        Order or1 = new Order();
        or1.orderId = 1001;
        Order or2 =or1;//赋值以后,or1和or2指向堆空间中同一个对象实体
        System.out.println("or1.orderId:"+or1.orderId+
                ",or2.orderId:"+or2.orderId);//两个输出的都是1001
        or2.orderId= 1002;
        System.out.println("or1.orderId:"+or1.orderId+
                ",or2.orderId:"+or2.orderId);
        /*
        两个输出的都是1002,因为or2和or1指向的都是同一个对象,
        当修改or2的参数时,此对象的参数就变为修改后的参数
        所以输出的结果都为:1002
        */
    }
}
class Order{
    int orderId;
}
错误示例

写方法时不能使用值传递,因为不会改变原参数的

解决方法:可以使用引用传递来进行参数调整

package OOP.ValueTransferText2;

public class ValueTransferText2 {
    public static void main(String[] args) {
        int x = 10;
        int y = 20;
        System.out.println(x+"--"+y);//输出10--20
        ValueTransferText2 val = new ValueTransferText2();
        val.swap(x,y);
        System.out.println(x+"--"+y);
        /*输出的是还是10--20
        这个操作相当于i=x;
        j=y;
        temp = i;
        i=j;
        j=temp;
        对于原值,x、y是没有改变的
         */
    }
    public void swap(int i,int j){
        int temp = i;
        i=j;
        j=temp;
    }
}

引用数据类型传递

引用传递使用:交换数据值
  1. 使用引用传递调换值
package OOP.ValueTransferText2;
public class ValueTransferText2 {
    public static void main(String[] args) {
        Date date = new Date();
        date.x=10;
        date.y=20;
        System.out.println("date.x:\t"+date.x+"\tdate.y:\t"+date.x);
        ValueTransferText2 v2 = new ValueTransferText2();
        v2.swap(date);
        System.out.println("date.x:\t"+date.x+"\tdate.y:\t"+date.y);
    }
    public void swap(Date date){
        int temp = date.x;
        date.x = date.y;
        date.y=temp;
    }
}
class Date{
    int x,y;
}
  1. 创建调换位置的方法,在冒泡排序中进行调用
package OOP.ValueTransferText2;
import java.util.Arrays;
public class ValueTransferText2 {
    public static void main(String[] args) {
        //要调用本类中的方法
        ValueTransferText2 v2 = new ValueTransferText2();
        int[] x = new int[]{1,-2,30,9,7,25,15};
        for (int i = 0; i < x.length; i++) {
            for (int j = 0; j < x.length-1-i; j++) {
                if (x[j]>x[j+1]){
                    v2.swap(x,j,j+1);
                }
            }
        }
        System.out.println(Arrays.toString(x));
    }
    //创建方法时,调换数组中的参数,应为数组是引用数据类型,可以达到调换位置的目的
    public void swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j]=temp;
    }
}

练习

1.创建一个类,让他包含一个double类型的半径(Radius),一个findAreas()方法返回一个double类型圆的面积
2.创建一个PassObject类,在类中定义一个方法printAreas(), 该方法的定义如下:public void printAreas(Circle circle,int time)。在printAreas中打印出1到time之间每个整数半径值,以及其对应的面积,

package OOP.ValueTransferText2;
/**
 * 1.创建一个类,让他包含一个double类型的半径(Radius),一个findAreas()方法返回一个double类型圆的面积
 * 2.创建一个PassObject类,在类中定义一个方法printAreas()
 * 该方法的定义如下:public void printAreas(Circle circle,int time)
 * 在printAreas中打印出1到time之间每个整数半径值,以及其对应的面积,
 */
public class ValueTransferText2 {
    public static void main(String[] args) {
        System.out.println("Radius\tArea");
        Circle circle = new Circle();
        PassObject pso = new PassObject();
        pso.printAreas(circle,6);
    }
}
class Circle{
    double radius;
    public double findAreas(){
        return Math.PI*radius*radius;
    }
}
class PassObject{
    public void printAreas(Circle c,int time){
        int i = 1;
        for (; i < time ; i++) {
            c.radius = i;
            System.out.println(c.radius+"\t\t"+c.findAreas());
        }
        System.out.println("\n"+"now radius is:"+ (double)i);
    }
}

递归

  • 递归方法:一个方法体调用它自身。
  • 方法递归包含了一种隐式的循环,他会重复执行某段代码,但这种重复执行无需循环控制。
  • 递归一定要向已知方向递归,否则这种地柜就变成了无穷递归,类似于死循环。
  • 例1:求1~n的自然数之和
package OOP.ValueTransferText2;
public class ValueTransferText2 {
    public static void main(String[] args) {
        System.out.println(getSum(100));
    }
    //创建一个求从1到n的自然数之和方法
    public static int getSum(int n){
        if (n==1){
            return 1;
        }else {
            return n+getSum(n-1);
        }
    }
}
  • 例2求1~n的自然数阶乘
package OOP.ValueTransferText2;
public class ValueTransferText2 {
    public static void main(String[] args) {
        System.out.println(getSum(100));
    }
    //创建一个求1~n的自然数阶乘的方法
    public static int getSum(int n){
        if (n==1){
            return 1;
        }else {
            return n*getSum(n-1);
        }
    }
}
  • 例3,一直有一个数列:f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值
package OOP.ValueTransferText2;
public class ValueTransferText2 {
    public static void main(String[] args) {
        System.out.println(getSum(10));
    }
    //创建一个求从1到n的自然数之和
    public static int getSum(int n){
        if (n==0){
            return 1;
        }else if(n==1) {
            return 4;
        }else {
            return 2*getSum(n-1)+getSum(n-2);
        }
    }
}
  • 例4,输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值,1 1 2 3 5 8 13 21 34 55
package OOP.ValueTransferText2;
public class ValueTransferText2 {
    public static void main(String[] args) {
        System.out.println(fbArr(10));
    }
    //斐波那契数列的第n个值的方法
    public static int fbArr(int n){
        if (n==1||n==2){
            return 1;
        }else {
            return fbArr(n-1)+fbArr(n-2);
        }
    }
}
  • 例5,汉诺塔问题
  • 例6,快速排序

复习

1.匿名对象的使用

2.理解万事万物皆对象

3.方法的重载

  • 方法的重载与重写的区别?

4.Java方法中的值传递机制

  • 基本数据类型变量:
  • 引用数据类型变量:
  • 形参和实参:方法的封装时使用的是形参,调用时是实参

5.return关键字的使用

6.递归

7.可变个数形参的方法,调用方法与数组一致

面向对象特征之一:封装

1.概述

  1. 为什么要封装?疯转的作用和含义?

    • 我要用洗衣机,只需要按一下开关和洗涤模式局可以了。没有必要了解洗衣机的内部结构、了解电动机的原理。

    • 开车—

  2. 程序设计追求“高内聚、低耦合”。

    • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉;

    • 低耦合:仅对外暴露少量的方法用于使用

  3. 3.隐藏对象内部的复杂性,支队挖公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。就是该藏的藏、该露的露。这就是封装性的设计思想。

2.问题的引入

  • 当我们创建一个类的对象后,我们可以通过“对象的.属性”的方式,对对象的属性进行复制。这里赋值操作要受到属性的数据类型和存储范围的制约
  • 加入额外的限制条件。这个条件就不能在属性声明是体现,我们只能通过方法进行限制条件的添加。比如(set同时我们需要避免面用户再使用“对象的.属性”的方法对属性进行赋值。则需要将属性声明为私有的额(private)–>此时,针对于属性就体现了封装)
package OOP.AnimalText;
//创建一个类,当使用此类时,保证属性的值都在合理范围内
public class AnimalText {
    public static void main(String[] args) {
        Animal p1 = new Animal();
        p1.variety = "human";
        p1.setHeight(168);
        p1.setLegs(2);
        p1.show();//打印属性
    }
}
class Animal {
    /*当直接调用属性时,因为不能规定输入范围。
    所以输入的范围可以是属性的数据类型的所有范围,而不是合理范围。
    我们可以通过将属性私有化,创建一个方法来对属性进行赋值,从而控制输入为合理范围,
    */
    String variety;
    private int legs;
    private double height;
    private int age;
    public void setLegs(int l){
        if (l>0 && l%2==0){
            legs =l ;
        }else {
            legs =0;
        }
    }
    public void setHeight(int h){
        if (h>0){
            height =h ;
        }else {
            height =0;
        }
    }
    public int getAge(){
        return age;
    }
    //打印属性
    public void show(){
        System.out.println("variety:"+variety+"\tage:"+legs+"\theight:"+height+"\tage:"+age);
    }
}

3.封装的体现

  • 我们将类的属性xxx私有化(private),同事,提供公共的(public)方法来获取(getXxx)和设置(setXxx)
  • 不对外暴露的私有的方法
  • 单例模式…

4.封装性的体现需要权限修饰符来配合

  1. Java规定的4中权限(从小到大):private、缺省、protected、public
package Order.O1;
public class Order2 {
    public static void main(String[] args) {
        Order1 o1 = new Order1();
        //public可以在本项目的所有类中使用
        o1.orderPublic = 1;
        //protected可以在不同包的子类中使用
        o1.orderProtected = 2;
        //缺省可以在本包下的所有类中使用
        o1.orderDefault = 3;
        //private只能在本类中使用
        //o1.orderPrivate = 4;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hlrOEYx8-1644334828457)(C:\Users\lin\AppData\Roaming\Typora\typora-user-images\image-20220118205302470.png)]

  1. 4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
  2. 只有public和缺省可以用来修饰类(非内部类)

总结封装

java提供了四种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构权限的大小

  • 创建一个Person类,定义一个私有属性age,使用set和get方法来体会封装
package OOP.Person;
public class PersonText {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setAge(26);
        System.out.println("age:"+p1.getAge());
    }
}
class Person {
    private int age;
    public void setAge(int a) {
        if (a>=0 && a<=130){
            this.age = a;
        }else {
            throw new RuntimeException("输入数据非法!");
        }
    }
    public int getAge() {
        return age;
    }
}

类的成员三:构造器(构造方法)

一、构造器的作用

  1. 创建对象

    • Person p1 = new Person();//后面的这个Person()就是Person类中的构造器
  2. 初始化对象的属性

    • public class PersonText {
          public static void main(String[] args) {
              Person person = new Person("Tom");
          }
      }
      class Person {
          String name;
          int age;
          //调用该类时初始化显示一些内容
          public Person(){
              System.out.println("Person()");
          }
          //初始化对象属性的构造器
          public Person(String n){
              name = n;
          }
      }
      

二、说明

  1. 如果没有显式的构造器的话,系统默认提供一个空参构造器
  2. 定义构造器的方法:权限修饰符 类名(形参){//方法体}
  3. 一个类中可以存在多个构造器,就是构造器的重载
  4. 构造器和方法的异同
    • 不同:声明方式不同
    • 相同:都可以进行重载
  5. 一旦我们显式的定义了类的构造器之后,系统就不会再提供空参构造器(一旦挣钱,就不给低保了)
  6. 一个类中,至少存在一个构造器

三、练习

  1. 在Person类中添加构造器,利用构造器设置所有人的age属性初始值都为18。
package OOP.Person;
public class PersonText {
    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println(p1.getAge());
    }
}
class Person {
    String name;
    private int age;
    public Person(){
        age = 18;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return age;
    }
}
  1. 修改上题中的类和构造器,增加name属性,使得每次创建Person对象时初始化对象的age和name
package OOP.Person;
public class PersonText {
    public static void main(String[] args) {
        Person p1 = new Person("小林",25);
        System.out.println("name:"+p1.getName()+"\tage:"+p1.getAge());
    }
}
class Person {
    String name;
    private int age;
    public Person(String n,int a){
        name = n;
        age = a;
    }
    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public Person(){
    }
}
  1. 编写两个类,TriAngle和TriAngleText,其中TriAngle类中声明私有的边长base和高height,同事声明公告的方法访问私有变量,提供类必要的构造器。另一个类中使用这些公共方法,计算三角形的面积
package OOP.TriAngle;

public class TriAngleText{
    public static void main(String[] args) {
        TriAngle t1 = new TriAngle();
        t1.setBase(5.1);
        t1.setHeight(5.2);
        System.out.println("Base:"+ t1.getBase()+"\tHeight:"+ t1.getHeight()+"\tArea:"+ t1.getArea());
    }
}

class TriAngle {
        private double base;
        private double height;

    public TriAngle(double b,double h){
          base = b;
          height = h;
        }

        public TriAngle(){

        }

    public double getBase() {
        return base;
    }

    public void setBase(double base) {
        this.base = base;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public double getArea(){
        return base*height;
    }
}
  1. 定义Student类,
    1. 有四个属性:String name; int age; String school; String major;
    2. 三个构造器:
      1. 第一个构造器Student(String n, int a)设置类的name和age;
      2. 第二个构造器Student(String n, int a,String s)设置类的name、age和school;
      3. 第三个构造器Student(String n, int a,String s,String m)设置类的name、age、school和major属性;
    3. 在main方法中分别调用不同的构造器创建对象,并输出其属性值

四、总结

  • 类中属性赋值的顺序:默认初始化–>显式初始化–>构造器赋值–>通过“对象.方法”或者“对象.属性”进行赋值
  • 前面三个赋值都只执行一次,可以叫初始化,后面的可以多次反复执行
  • 默认构造器的权限与类的权限一致
  • 在一个类中创建另一个类类型的属性,这叫做关联

JavaBean–拓展知识

  • JavaBean是一种Java语言写成的可重用组件
  • 所谓JavaBean,是指符合如下标准的Java类:
    • 类是公告的
    • 有一个无参的构造器
    • 有属性,且有对应的get、set方法
  • 用户可以使用JavaBean将功能、处理、值、数据库访问和其他的任何可以使用Java代码创造的对象进行打包,并且其他的开发者可以通过JSP页面、Servlet、其他的JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变

this关键字的使用

this是什么?

  • 在Java中,this关键字比较难立即,它的作用和其词义很接近。
    • 它在方法内部使用,即这个方法所属对象的引用;
    • 它在构造器内部使用,表示该构造器正在初始化的对象
  • this表示当前正在创造的对象,可以调用类的属性、方法和构造器
  • 什么时候使用this关键字呢?
    • 当在方法内需要调用到该方法的对象是,就用“this.属性”或“this.方法”。但在大部分情况下,我们都选择省略“this.”。如果方的的形参与类的属性同名时,我们必须显式的使用“this.变量”的方式,表明此变量是属性,而非形参。
    • 具体的:我们可以使用this来区分局部变量和属性。
    • 比如:this.name=name

this调用构造器

  • 我们在类的构造器中,可以显式的使用“this(形参列表)”方法,调用本类中制定的其他构造器
  • 构造器中不能通过“this(形参列表)”方式调用自己
  • 如果一个类中有n个构造器,则最多有n-1构造器中使用了“this(形参列表)”
  • 规定:“this(形参列表)”必须声明在当前构造器的首行
  • 构造器内部,最多只能声明一个“this(形参列表)”,用来调用其他的构造器

练习一复习

简易银行

package OOP.BankText;
/*测试
*
 */
public class BankText {
    public static void main(String[] args) {
        Bank bank = new Bank();
        bank.addCustomer("Jane","Smith");
        bank.getCustomer(0).setAccount(new Account(2000));
        bank.getCustomer(0).getAccount().withdraw(500);
        System.out.println("客户:"+bank.getCustomer(0).getFirstName()+","+
                bank.getCustomer(0).getLastName()+",余额为:"+
                bank.getCustomer(0).getAccount().getBalance());
        System.out.println("***********************");
        bank.addCustomer("狗蛋","小");
        System.out.println("银行现在的客户数量为:"+bank.getNumberOfCustomer());
    }

}
/*
*创建银行类
* - customers : Customer[]
* - numberOfCustomer : int
* _____+Bank()
* + addCustomer(String f,String l)
* + getNumberOfCustomer() : Customer
 */
class Bank {
    private Customer[] customers;
    private int numberOfCustomer;
    public Bank(){
        customers = new Customer[10];
    }
    public void addCustomer(String f,String l){
        customers[numberOfCustomer++] = new Customer(f,l);
    }

    public int getNumberOfCustomer() {
        return numberOfCustomer;
    }

    public Customer getCustomer(int index){
        if (index >=0 && index<numberOfCustomer){
            return customers[index];
        }
        return null;
    }
}
/*创建Customer类
* - firstName :String
* - lastName :String
* - account :Account
* ___+Customer(f:String, l:String )
* + getFirstName() : String
* + getLastName() : String
* + getAccount() : String
* + setAccount(int)
 */
class Customer {
    private String firstName;
    private String lastName;
    private Account account;

    public Customer(String f,String l){
        firstName = f;
        lastName = l;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Account getAccount() {
        return account;
    }

    public void setAccount(Account account) {
        this.account = account;
    }
}

/*创建Account类
 * -balance :double
 * ___+Account(init_balance:double)
 * + getBalance(double)
 * + setBalance() : double
 * + setBalance() : double
 * + deposit(double:amt)
 * + withdraw(double:amt)
 */
class Account {
    private double balance;
    public Account(double init_balance){
        balance = init_balance;
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amt){
        if (amt > 0){
            balance+=amt;
            System.out.println("成功存入:"+amt+"!");
        }
    }
    public void withdraw(double amt){
        if (amt>0 && amt <= balance){
            balance-=amt;
            System.out.println("成功取出:"+amt+"!");
            return;
        }
        System.out.println("取款失败:余额不足!");
    }
}

项目二:客户信息管理软件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RPWIGbt6-1644334828457)(C:\Users\lin\AppData\Roaming\Typora\typora-user-images\image-20220123151528541.png)]

添加用户,删除用户,修改用户信息,查询用户信息

面向对象(中)

面向对象特征二:继承性(inhertance)

一:继承性的好处:(Why?)

  • 减少代码的冗余,提高代码的复用性
  • 便于功能的扩展
  • 为了以后多态的使用提供了前提

二:继承性的格式:class A extends B{}

  • A:子类、派生类、subclass
  • B:父类、超类、基类、superclass
    • 2.1 体现:子类A一旦继承到父类B之后,子类会获得父类所有的属性和方法
      特别的,父类结构中声明的private属性和方法,子类继承父类后,任然认为获取了父类中私有的结构
      只是因为封装性的影响,子类不能直接调用父类中private的结构
    • 2.2 子类继承父类后,可以声明自己的属性和方法,实现功能的扩展。
      子类和父类的关系,不同于集合与子集的关系

? extends:扩展、延展

三:Java中关于继承性的一些规定

  1. 一个类可以允许多个子类继承。
  2. Java中类的单继承性:一个子类只能有一个父类。(C++中可以多继承)
  3. 子类是相对概念
  4. 子类直接继承的父类叫直接父类,间接继承的类叫间接父类
  5. 子类继承父类后,也继承了所有间接父类的结构

  1. 所有的类都继承与java.lang.Object(除了它本身)类
  2. 意味着所有的类都具有java.lang.Object声明的功能

继承性的复习

1.为什么要有类的继承性?(继承性的好处)

  1. 减少代码的冗余,提高代码的复用性
  2. 便于功能的扩展
  3. 为之后多态性的使用,提供了前提

2.继承性的格式

  • class A extends B{}

3.子类继承父类以后有哪些不同?

  • 子类继承父类后拥有父类的所有属性和方法
  • 子类可以声明属性及方法实现功能的扩展
  • 子类可以通过父类提供的public方法使用父类private的结构

4.java.lang.Object类的理解

  • 所有的类都继承与java.lang.Object(除了它本身)类
    public void deposit(double amt){
    if (amt > 0){
    balance+=amt;
    System.out.println(“成功存入:”+amt+"!");
    }
    }
    public void withdraw(double amt){
    if (amt>0 && amt <= balance){
    balance-=amt;
    System.out.println(“成功取出:”+amt+"!");
    return;
    }
    System.out.println(“取款失败:余额不足!”);
    }
    }

## 项目二:客户信息管理软件

[外链图片转存中...(img-RPWIGbt6-1644334828457)]

添加用户,删除用户,修改用户信息,查询用户信息

# 面向对象(中)

## 面向对象特征二:继承性(inhertance)

### 一:继承性的好处:(Why?)

- 减少代码的冗余,提高代码的复用性
-  便于功能的扩展
-  为了以后多态的使用提供了前提

###  二:继承性的格式:class A extends B{}
- A:子类、派生类、subclass
- B:父类、超类、基类、superclass
  - 2.1 体现:子类A一旦继承到父类B之后,子类会获得父类所有的属性和方法
              特别的,父类结构中声明的private属性和方法,子类继承父类后,任然认为获取了父类中私有的结构
              只是因为封装性的影响,子类不能直接调用父类中private的结构
  - 2.2 子类继承父类后,可以声明自己的属性和方法,实现功能的扩展。
          子类和父类的关系,不同于集合与子集的关系

?     extends:扩展、延展

### 三:Java中关于继承性的一些规定
1. 一个类可以允许多个子类继承。
2. Java中类的单继承性:一个子类只能有一个父类。(C++中可以多继承)
3. 子类是相对概念
4. 子类直接继承的父类叫直接父类,间接继承的类叫间接父类
5. 子类继承父类后,也继承了所有间接父类的结构

### 四

1. 所有的类都继承与java.lang.Object(除了它本身)类
2. 意味着所有的类都具有java.lang.Object声明的功能

### 继承性的复习

1.为什么要有类的继承性?(继承性的好处)

1. 减少代码的冗余,提高代码的复用性
2. 便于功能的扩展
3. 为之后多态性的使用,提供了前提

2.继承性的格式

- class A extends B{}

3.子类继承父类以后有哪些不同?

- 子类继承父类后拥有父类的所有属性和方法
- 子类可以声明属性及方法实现功能的扩展
- 子类可以通过父类提供的public方法使用父类private的结构

4.java.lang.Object类的理解

- 所有的类都继承与java.lang.Object(除了它本身)类
- 意味着所有的类都具有java.lang.Object声明的功能
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-09 20:33:44  更:2022-02-09 20:35:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:38:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码