Day03

本文深入解析Java中数组的使用、内存分配、面向对象编程原理,包括数组边界、动态与静态初始化、值传递与引用传递,以及封装、继承、多态等核心概念。通过实例演示,理解数组应用、排序算法和面向对象编程的最佳实践。
摘要由CSDN通过智能技术生成

数组

package com.lv.array;

public class ArrayDemo01 {


    //变量的类型    变量的名字   =   变量的值;
    public static void main(String[] args) {
        int[] num;//两种声明方法    首选方法
      //  int num2[];
        int sum=0;
        num=new int[10];//这里可唔可以存放10个int类型的数组
        //给数组元素赋值
        num[0]=1;
        num[1]=2;
        num[2]=3;
        num[3]=4;
        for (int i = 0; i <num.length; i++) {//    获取数组长度   arrays.length

           sum=num[i]+sum;//求所有数的和
        }


        System.out.println(sum);
    }
}

内存分析

​ 存放new的对象和数组

​ 堆 可以被所有的线程共享,不会存放别的对象引用

​ 存放基本变量类型(会包含这个基本类型的基本数值)

Java 栈 引用对象的变量(会存放这个引用在堆里面的具体地址)

​ 可以被所有的线程共享

​ 方法区 包含了所有的 class和static变量

静态初始化

int [] a={1,2,3};
Man[] mas ={new Man(1,1),new Man(2,2)}

动态初始化

int[] a= new int[2];
a[0]=1;
a[1]=2;

数组默认初始化

数组是引用类型,他的元素相当于类的变量,因此数组一经分配,其中的每一个元素也被按照实例变量同样的方式被隐式初始化。

package com.lv.array;

public class ArrayDemo02 {
    public static void main(String[] args) {
        //静态初始化
        int[] a={1,2,3,4,5};
        System.out.println(a[3]);
        System.out.println("========================================");

       //动态初始化   包含默认初始化
        int[] b=new int[10];
        b[0]=2;
        System.out.println(b[0]);


    }


}

数组边界

  • 数组是相同数据类型(数据类型可以为任意类型)的有序集合
  • 数组也是有对象的,数组元素相当于对象的成员变量
  • 数组长度确定,不可变的,如果越界则会报错 ArrayIndeOutofBounds

数组的一些应用

package com.lv.array;

public class ArrayDemo03 {
    public static void main(String[] args) {
        int[] array= {1,2,3,4,5};
        int sum=0;
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);//打印数组的元素

            //计算数组的总和

            sum=sum+array[i];
        }
        System.out.println(sum);
        //找出数组中最大的数
        int max=array[0];
        for (int i = 0; i < array.length; i++) {
            if(max>array[i]){
                max=max;
            }else{
                max=array[i];
            }
        }
        System.out.println(max);
    }
}
package com.lv.array;

public class ArrayDemo04 {
    public static void main(String[] args) {
        int[] array={1,2,3,4,5};
        int[] reverse=reverse(array);

       prinArray(reverse);
       
    }
    //将数组元素反过来
    public static int[] reverse(int[] array){

        int[] result=new int[array.length] ;
        for (int i = 0,j=result.length-1; i <array.length;i++,j--) {

            result[j]=array[i];

        }
        
        return result;
    }

//打印数组元素
    public static void prinArray(int[] array){
        for (int i = 0; i < array.length ;i++) {
            System.out.println(array[i]);

        }
      

    }


}

二维数组

package com.lv.array;

public class ArrayDemo05 {
    public static void main(String[] args) {
        int[] array={1,2,3,4,5};


        //=========================================
        int[][] arrays= {{1,2},{2,3}};//二维数组
        for (int i = 0; i < arrays.length; i++) {
            for (int j = 0; j < arrays[i].length; j++) {
                System.out.println(arrays[i][j]);
            }
        }
        printArray(arrays[1]);//打印数组元素
    }
    //打印数组元素
    public static void printArray(int[] array){
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);

        }
    }
}

Arrays的一些运用

package com.lv.array;

import java.util.Arrays;

public class ArrayDemo06 {
    public static void main(String[] args) {
        int[] a={1,2,3,34,5,6,7};
        Arrays.sort(a);//数组重新排序
        System.out.println(Arrays.toString(a));//打印数组元素
        Arrays.fill(a,2,4,0);//数组的填充
        System.out.println(Arrays.toString(a));//打印数组元素

    }


}

冒泡排序

冒泡排序是最为出名的排序算法之一,总共有八大排序算法

package com.lv.array;
//冒泡排序
    /*
    1.比较数组中两个相邻的元素,如果第一个比第二个元素大,就交换他们的位置;
    2.每一次比较都会产生出一个最大,或者最小的数字;
    3.下一轮则可以少一次排序;
    4.依次循环直到结束;
     */


import java.util.Arrays;

public class ArrayDemo07 {
    public static void main(String[] args) {
//
//       int[] a={1,2,4,5,9,} ;
//        int[] sort = sort(a);//调用完我们自己写的排序方法以后,返回一个排序过后的数组;
//        System.out.println(Arrays.toString(a));
//
//    }
//    public static int[] sort(int[] a){
//        int temp=0;//临时变量;
//        for (int i = 0; i < a.length-1; i++) {//外层循环,判断我们的循环要走多少次;
//            for (int j = 0; j < a.length-1-i; j++) {//内层循环;
//               //比较两个数,如果第一个比第二个元素大,就交换他们的位置;
//                if (a[j]>a[j+1]){
//                    temp=a[j];
//                    a[j]=a[j+1];
//                    a[j+1]=temp;
//
//                }
//            }
//
//        }
//        return a;
//
//        int[] array={1,2,3,4,5,4,3,2,1};
//
//        int[] sort = sort(array);
//        System.out.println(Arrays.toString(array));
//
//
//    }
//    public static int[] sort(int[] array){
//        int temp=0;
//        for (int i = 0; i < array.length-1; i++) {
//            for (int j = 0; j < array.length-i-1; j++) {
//                if (array[j]>array[j+1]){
//                    temp=array[j];
//                    array[j]=array[j+1];
//                    array[j+1]=temp;
//                }
//
//            }
//
//        }
//        return array;
        int[] b={3,6,34,6,7,654,78,8,2,11,1423};
        int[] sort = sort(b);
        System.out.println(Arrays.toString(sort));

    }
    public static int[] sort(int[] b){
        int temp;
        for (int i = 0; i < b.length-1; i++) {
            for (int j = 0; j < b.length-1-i; j++) {
                if (b[j]>b[j+1]){
                    temp=b[j];
                    b[j]=b[j+1];
                    b[j+1]=temp;

                }

            }

        }
        return b;
    }

}

面向对象

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

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

package com.oop.demo01;
//Demo01 类
public class Demo01 {
    //main方法
    public static void main(String[] args) {
        /*
        修饰符   返回值类型  方法名(···){
        方法体;
        return   返回值;
         */
    }
    //return 结束方法    返回一个结果!;
    public String sayHello(){
        return "hello world!";
    }
    public void print(){
        return;
    }
    public int max(int a,int b){
        return  a>b?a:b;//三元运算符,如果a>b则输出a,否则输出b;
    }
}

方法复习

package com.oop.demo01;

public class Demo02 {
    //静态方法     使用static
    public static void main(String[] args) {
        Student.say();//静态方法可以使用类名.方法名调用
        //=========================================

        //实例化这个类 new
        //对象类型 对象名=对象值
        Student student = new Student();//非静态调用方法
        student.say1();
        System.out.println(student);

    }


    //非静态方法
}
package com.oop.demo01;
//学生类
public class Student {
    //方法
    //这里是  静态方法   没有使用 static
    public static void  say(){
        System.out.println("学生说话了");

    }
    //非静态方法   没有static
    public void say1(){
        System.out.println("学生又说话了");

    }
}

值传递 和 引用传递

值传递

package com.oop.demo01;
//值传递
public class Demo04 {
    public static void main(String[] args) {
        int a=1;
        System.out.println(a);

        Demo04.change(a);
        System.out.println(a);


    }

    //返回值为空
    public static void change(int a){
        a=10;
    }

}

引用传递

package com.oop.demo01;
//引用传递  传递对象,其本质还是值传递
public class Demo05 {
    public static void main(String[] args) {
        Perosn perosn = new Perosn();
        System.out.println(perosn.name);
        change(perosn);
        System.out.println(perosn.name);


    }
    public static void change(Perosn perosn){
        //perosn 是一个对象---->指向Perosn perosn=new Perosn(); 这里是具体的人,可以改变属性;
        perosn.name="lv";
    }


}


///定义了一个Perosn类,有一个属性:name
class Perosn{
    String name ;
}

new

package com.oop.demo02;

public class Student {
    //属性: 字段
    String name;//默认初始null
    int age;//默认0;
    //方法
    public  void study(){
        System.out.println(this.name+"学生在学习");
    }
}


面向对象编程的本质是:以类的方式组织代码,以对象的形式组织(封装)数据;
package com.oop.demo02;

public class Application {
    public static void main(String[] args) {
        //类 抽象的,实例化
        /*
        new 关键之创建的的时候,除了分配空间之外
        还会给创建的对象 默认初始化   以及构造器的调用
         */

        Student xiaoMing = new Student();
        Student xiaoLing = new Student();
        Student xiaoXing = new Student();
        xiaoMing.name="小明";
        xiaoMing.age=15;
        System.out.println(xiaoMing.name +xiaoMing.age);



    }
}

创建初始化对象

new 关键之创建的的时候,除了分配空间之外还会给创建的对象 默认初始化 以及构造器的调用


类的构造器也称为构造方法,实在惊醒创建对象的时候必须调用的,并且构造器有以下两个特点:

  1. 必须和类名相同;
  2. 必须没有返回值类型,也不能写void

构造器

package com.oop.demo02;

public class Person {
    //一个类即使什么都不写,他也会存在一个方法
    //必须和类的名字相同
    // 必须没有返回值,不能有void
    String name;
    //可以实例化初始值
    //使用new关键字 本质是在调用构造器   2.用来初始化值
    public Person() {//无参构造
    }
    public Person(String name){//有参构造,一旦定义了有参构造,无参构造就必须显示定义
        this.name=name;

    }
//==============================
    //alt +insert 快捷有参和无参构造器
//
//    public Person(String name) {
//        this.name = name;
//    }
//
//    public Person() {
//    }
public static void main(String[] args) {

    //new关键字 实例化了一个对象
    Person person = new Person("lv");
    System.out.println(person.name);

}

}
/*
    构造器:
        1.和类名相同
        2.没有返回值
    作用:
        1.new 本质是调用构造器
        2.初始化对象的值
    注意点:
        1.定义了有参构造,如果想使用无参构造,必须显示定义一个无参构造
    alt+insert     
    
 */

内存分析

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

package com.oop.demo03;

public class Pet {
    public String name;
    public int age;
    public void shot(){
        System.out.println(this.name+"叫了一声");
    }
    public static void main(String[] args) {
        Pet dog = new Pet();
        dog.name="旺财";
        dog.age=3;
        Pet cat = new Pet();
        cat.name="凯特";
        cat.age=2;
        System.out.println(dog.name);
        System.out.println(dog.age);
        System.out.println(cat.name);
        System.out.println(cat.age);

    }

}

小节 回顾

package com.oop.demo03;

public class Demo01 {
    /*
    1.类与对象
    类是一个模板:抽象,对象是一个具体的实例
    2.方法
    定义 、调用
    3.对应的引用
    引用类型  基本类型(8)
    对象是通过引用来操作的    栈--->堆
    4.属性: 字段field 成员变量
    默认初始化:
    数字:    0  0.0
    char:   u0000
    boolean:false
    5.对象的创建和使用
    ---必须使用new创建对象,构造器   Person lv = new Person;
    ---对象的属性                 lv.name;
    ---对象的方法                 lv.sleep();
    6.类
        静态的属性   属性
        动态的方法   方法
    7. 封装、继承、多态
     */


}

封装

程序设计要追求:“高内聚,低耦合”。高内聚就是类的内部操作细节自己完成,不允许 外部干涉,低耦合 :仅暴露少量的方法给外部使用

封装(数据的隐藏)

通常应禁止直接访问一个对象中的数据的实际表现,而应通过操作接口来访问,这称为信息隐藏

属性私有,get/set

package com.oop.demo04;

import java.util.Scanner;

//类
public class Student {
    //private 私有
    private String name;
    private int age;
    private char sex;
    /*
    1.提高了程序的安全性,保护数据;
    2.隐藏代码的实现细节;
    3.统一接口;
    4.系统的可维护性增加了;
     */

    public void study(){
        System.out.println("学生学习");
    }
    //get 获得这个数据
    public String getName() {    //alt + insert;快捷生成get/set
        return name;
    }
    //set 为这个数据设置值
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >120||age<0){
            System.out.println("你输入的年龄误");
        }else{
            this.age = age;
        }
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }
    //===========================================================
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Student lv = new Student();
        lv.setName("lv");
        lv.study();
        System.out.println(lv.getName());
        System.out.println("请输入你的年龄");
        lv.setAge(scanner.nextInt());
        if (lv.getAge()!=0) {
            System.out.println("你的年龄为" + lv.getAge() + "岁");
        }



    }
}

继承

继承的本质是对某一批的抽象类,从而实现对现实世界更好的建模

extends 的意思是 “拓展”.子类是父类的拓展;

JAVA中类只有继承,没有多继承;(一个爸爸可以有多个儿子,但是一个儿子只有一个爸爸)


继承是类和类之间的一种关系。除此之外,类和类之间的关系还有 依赖、组合、聚合等。

继承关系的俩类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键之extends来表示。

子类和父类之间,从意义讲应该具有“is a“的关系。

public class Student extends Person{
    
}

私有的将无法被继承

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

子类将会继承父类的全部方法


object类

super类

方法重写

在Java中都默认直接或间接继承object类 //alt+h 调出继承树


super注意点:

  1. super调用父类的构造方法,必须在构造方法的第一个
  2. super必须只能出现在子类的方法或者构造方法中
  3. super和this不能同时调用构造方法

VS this:

代表的对象不同:

​ this: 本身调用者这个对象

​ super:代表父类对象的应用

前提:

​ this:没有继承也可以使用

​ super:只能在继承条件才可以使用

构造方法

​ this(); :本类的构造

​ super(); :父类的构造


package com.oop;

import com.oop.demo05.Student;

import java.util.Scanner;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
//        System.out.println(student.age);
//        student.test();

    }




}
package com.oop.demo05;

public class Student extends Person {

       private String a="你好1";

    public Student() {
        super();
        //这是隐藏的代码,调用了父类的无参构造
        //调用父类的构造器,必须在子类构造器的第一行
        System.out.println("调用了子类的Student");
    }

    public void prinnt(){
        System.out.println("你好3");
    }
    public void test(){
        prinnt();
        say("你好");
        System.out.println(this.a);
        System.out.println(super.a);
    }
}
package com.oop.demo05;

public class Person {
     public int age=10;
     public   String a="你好2";
     public void say(String a){
         System.out.println("你好");


     }

     public Person() {
          System.out.println("调用了父类的Perspn");
     }
}

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

重写 :需要有继承关系, 子类重写父类的方法!

  1. 方法名必须相同
  2. 参数列表必须相同
  3. 修饰符:范围可以扩大 Public >Protected>Default>Private
  4. 抛出的异常: 范围可以被缩小 但不能扩大

重写 , 子类的方法和父类必须一致,方法体不同

package com.oop;


import com.oop.demo05.A;
import com.oop.demo05.B;

public class Application {
    public static void main(String[] args) {


        //静态方法和非静态方法有区别 static
        //静态方法: 方法的调用只左边有关(定义的数据类型)

        //非静态  重写   !public
        B a=new B();
        a.test();
        //父类的引用指向子类
        B b=new A();//子类重写了父类的方法
        b.test();
    }


}
package com.oop.demo05;

public class A extends B{
    @Override//注解  有功能的注释  override 翻译:重写
    public void test() {
        System.out.println("A=>test");
    }


    //    public  void test(){
//        System.out.println("A=>test");
//    }
}
package com.oop.demo05;

public class B {
    public  void test(){
        System.out.println("B=>test");
    }
}

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

思考 为什么需要重写

	1. 父类的功能,子类不一定需要,或不一定满足!
	2. alt +insert 

多态

动态编译: 类型:可扩展性

即同一方法可以根据发送对象不同二采用不同的行为方式。

一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多

package com.oop;

import com.oop.demo06.Person;
import com.oop.demo06.Student;

public class Application {
    public static void main(String[] args) {


        //一个对下个的实际类型是确定发
        //new Student()
        //new Person()
        //可以指向的引用类型就不确定了,父类的引用指向了类
        //
        //
        //Student 能调用的方法都是自己的或者继承父类的

        Student st2=new Student();
        //Person 父类型,指向子类,但是不能调用子类独有的方法
        //意思是子类和父类都有同一种方法
        Person st1 = new Student();
        Object st3=new Student();
        //对象能执行哪些方法,只要看左边的的类型,和右边的关系不大
        st1.eat();
        st2.run();

    }


}
package com.oop.demo06;

public class Student extends Person {
    public void eat(){
        System.out.println("eat子");
    }
    public void run(){
        System.out.println("run子");
    }
}
package com.oop.demo06;

public class Person {
    public void run (){
        System.out.println("run父");
    }
    public void eat(){
        System.out.println("eat父");
    }
}

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

多态存在的条件

  1. 有继承关系
  2. 子类重写父类方法
  3. 父类引用指向类的对象

注意: 多态是方法的多态,属性没有多态性;


多态的注意事项

  1. 多态是方法的多态,属性是没有多态的
  2. 父类和子类 ,有联系, 类型转换异常!classCastException!
  3. 存在的条件: 继承关系 、 方法重写 、 父类引用指向子类对象

​ 不能重写 :

			1. static 方法,属于类,不属于实例
			2. final 常量,无法改变
			3. private   私有,

Instanceof 类型转换 指的是引用类型的转换

package com.oop;

import com.oop.demo07.Person;
import com.oop.demo07.Student;

public class Application {
    public static void main(String[] args) {

        //高-------------------------低(低到高自动转换)
        // Student类可直接转换为Person类型
        Person student = new Student();
//        student.go;    这里不能使用go方法   因为student 为Person类 这个类里面没有go()方法
        //所以需要把student强制转换为Student类才能调用go()方法



        Student student1 = (Student) student;//   (Student)student;
        student1.go();

        //上面代换可以简化为下面的代码
        ((Student)student).go();


        Student student2 = new Student();
        Person person=student2;


//        person.go();//将子类Student转化为父类Person,这里的go()方法不能使用了
        // 可能会丢失自己本来的一些方法


    }


}
package com.oop.demo07;

public class Student extends Person {
    public void go(){
        System.out.println("go");
    }
}

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

  1. 父类的引用指向子类的对象
  2. 把子类转换为父类 向上转型 自动转换 低------------>高
  3. 把父类转换为子类 向下转型 强制转换 高------------>低 可能会丢失原来的方法
  4. 方便方法的调用 减少代码的重复,让代码简介

抽象: 封装 – 继承 --多态 抽象类 接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值