1-java零基础学习视频通俗易懂

java使用规范

1、大小写敏感
2、尽量使用英文
3、文件名和类名一致,首字母大写

IDEA使用

一般建空项目,在项目中建立模块(也可以不建),然后在模块中建立类,类上面可以用软件包归类package

常用语法

//就是单行写注释

/* */多行注释

数据类型

基本类型
引用类型

//整数
int num1=10;//最常用
byte num2=20;
short num3=30;
long num4=30L;//long类型要在数字后面加个L

//小数,浮点数
float num5=50.1F;//float类型要在数字后面加F
double num6=3.124343;

//字符
char name="国“;//单字符
//字符串,String不是关键字,是类
//String name="陈陈";

//布尔值:是非
boolean flag=true;

类型转换

强制类型转换:高转换成低 -(类型)变量名

int i=128;
byte b=(byte)i

自动类型转换:低转换成高

int i=128;
double b=i

注意点:
布尔值不能转换
转换可能存在内存溢出问题

计算注意点

public class  Demo01 {
    public static void main(String[] args) {
        int money=10_0000_0000;
        int year=20;
        int total=money*year;//-1474836480
        long total2=money*year;//-1474836480,转换之前已经出现问题
        long total3=money*(long)year;//计算前先进行转换就不会出现问题20000000000
        System.out.println(total3);
    }
}

变量

变量作用域
类变量:加了static关键字,随着类出现,也随着类消失,static为修饰符
实例变量:从属于对象,如果不自行初始化,这个类型默认值为0,布什值为false,除了基本类型,其他主null
局部变量:是指在方法内的变量,必须声明和初始化值

public class Helloworld {
    static int allclicks = 0;//类变量
    String name = "Hello, World!";//实例变量
    public  void method1() {
        int i = 0;//局部变量
    }
}

例子

public class Helloworld {
    static double salary=25000;
    String name;
    int age;
    public static void main(String[] args) {
        int i = 10;
        System.out.println(i);//10
        Helloworld obj = new Helloworld();
        System.out.println(obj.name);//null
        System.out.println(obj.age);//0
        System.out.println(salary);//25000
    }
}

常量

final 常量类型 常量名 =值

命名规范

基本运算符

一元运算符,++,-- 自增 自减

public class  Demo01 {
    public static void main(String[] args) {
        int a=3;
        int b=a++;//b=3, a=4,a先赋值给了b,然后a自增,a++  a=a+1
        int c=++a;//c=5, a=5,a先自增,然后赋值给了c
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
    }
}

逻辑与运算

逻辑运算符

public class  Demo01 {
    public static void main(String[] args) {
        boolean a = true;
        boolean b = false;
        system.out.println(a && b); // false,一个为false则结果为false
        system.out.println(a || b); // true,一个为true则结果为true
        system.out.println(!a); // false,取反
    }
}

补充短路运算

public class  Demo01 {
    public static void main(String[] args) {
        //短路运算
        int a = 10;
        boolean b = (a<9)&&(a++>5);
        System.out.println(b); //输出false,第一个是false,第二个表达式a++>5不执行,所以a=10,所以b=false
        System.out.println(a); //输出10
    }
}

位运算符,底层

public class  Demo01 {
    public static void main(String[] args) {
        //位运算符
        /*
        A=00111100;
        B=00001101;
        A&B=00001100;
        A|B=00111101;
        A^B=00110001;
        ~A=11000011;
        2*8=16 2*2*2*2=16
        << *2
        >> /2
         */
        System.out.println(2<<3);//16
    }
}

扩展

public class  Demo01 {
    public static void main(String[] args) {
      int a = 10;
      int b = 5;
      a+=b; // a= a + b, a=15
      a-=b; // a = a - b
      //字符串连接符  +string
        System.out.println(""+a+b);//输出105,
        System.out.println(a+b+"");//输出15
    }
}

三元运算符

public class  Demo01 {
    public static void main(String[] args) {
       //x?y:z
        //如果x为true,则返回y,否则返回z
        int score = 85;
        String type=score>=90?"优秀":"良好";
        System.out.println(type);//输出:良好

    }
}

javadoc

/**
*@author
*@param
*/
文档能写在类中也能写在方法中
使用idea生产javadoc文档

JAVA流程控制

用户交互scanner

public class  Demo01 {
    public static void main(String[] args) {
        //从键盘接收数据
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter your text: ");
        String str = scanner.nextLine();//把Enter前的内容赋值给变量str,next是有空格就断了,比较少用
        System.out.println("你输入的内容是: "+str);
        scanner.close();//属于IO流,必须关闭,否则会一直执行,占用资源
    }
}

//固定语句,在里面输入
Scanner scanner = new Scanner(System.in);
..
scanner.close();

ctrl+类名可以查看这个类中有什么方法,
补充scanner其它方法

public class  Demo01 {
    public static void main(String[] args) {
        //从键盘接收数据
        Scanner scanner = new Scanner(System.in);
        int i=0;
        float f=0.0f;
        System.out.print("请输入整数:");
        if(scanner.hasNextInt()){//判断输入的是否为整数
            i = scanner.nextInt();
            System.out.println("整数为:" + i);
        }else{
            System.out.println("输入有误,请输入整数!");
        }
        scanner.close();//属于IO流,必须关闭,否则会一直执行,占用资源
    }
}

流程控制

if结构

public class  Demo01 {
    public static void main(String[] args) {
        if (布尔表达式) {
            
        }
    }
}
public class  Demo01 {
    public static void main(String[] args) {
        if (布尔表达式) {

        }else{
            
        }
    }
}
public class  Demo01 {
    public static void main(String[] args) {
        if (布尔表达式) {

        }else if (布尔表达式) {

        }else if (布尔表达式) {

        }else {
        }
}

switch结构

public class  Demo01 {
    public static void main(String[] args) {
        char grade = 'F';//switch现在也支持String类型
        switch (grade) {
            case 'a':
                System.out.println("Excellent");
                break;//如何没加break,会执行后面的语句
            case 'b':
                System.out.println("Good");
                break;
            case 'c':
                System.out.println("Satisfactory");
                break;
            case 'd':
                System.out.println("Pass");
                break;
            case 'f':
                System.out.println("Fail");
                break;
            default:
                System.out.println("未知等级");
        }
    }
}

把class文件拉到idea的src中可以进行反编译

while循环结构
while(布尔表达式){
循环内容
}

public class  Demo01 {
    public static void main(String[] args) {
        //输出1-100
        int i =0;
        while(i<100){
            i++;
            System.out.println(i);

        }
    }
}

Dowhile循环
do{
//代码语句
}while(布尔表达式)
与while的区别,while是先判断后执行,dowhile是先执行后判断

public class  Demo01 {
    public static void main(String[] args) {
        int a=0;
        while(a<0){
            System.out.println(a);
            a++;
        }
        System.out.println("========");
        do{
            System.out.println(a);
            a++;
        }while(a<0);
    }
}
//上面不输出任何东西,下面输出0

for循环
for(初始化;布尔表达式;更新){
//代码语句
}

public class  Demo01 {
    public static void main(String[] args) {
        int a=1;
        while(a<=100){
            System.out.println(a);
            a+=2;
        }
        System.out.println("whilt循环结束");
        for(int i=1;i<=100;i++){
            System.out.println(i);//输出1到100,逻辑就是和while循环一样,先执行print(循环体里面的代码模块),然后i++
        }
        System.out.println("for循环结束");

    }
}

增加for循环-一般是用于数组或集合
for(声明语句:表达式)
{
//代码句子
}

public class  Demo01 {
    public static void main(String[] args) {
        int [] numbers = {1, 2, 3, 4, 5};
        for(int x : numbers){
            System.out.println(x);
        }

    }
}

break强行退出循环

public class  Demo01 {
    public static void main(String[] args) {
        int i =0;
        while(i<100){
            i++;
            System.out.println(i);
            if(i==30){
                break;
            }
        }
    }
}

continue用于终止某次循环过程

public class  Demo01 {
    public static void main(String[] args) {
        int i =0;
        while(i<100){
            i++;
            if(i%10==0){
                System.out.println();
                continue;//当等于10时,直接跳过下面的代码,又回到while循环的开头,继续执行
            }
            System.out.print(i);
        }
    }
}
//123456789
//111213141516171819
//212223242526272829
//313233343536373839
//414243444546474849
//515253545556575859
//616263646566676869
//717273747576777879
//818283848586878889
//919293949596979899

goto了解就行,一般是配合标签跳到指定循环

多用Debug的方式调试,在对应的行打断点,点击飘虫,下面会输当前变量的值 ,然后再下一行,可以实时看到变量的值和程序的运行

方法

public class  Demo01 {
    public static void main(String[] args) {
        int sum = add(10, 20);
        System.out.println(sum);
    }
    //加法
    public static int add(int a, int b){
        return a+b;
    }

}

java的方法类似其他语言的函数,用来完成特定功能的代码片段

Java的包=python的库
Java的类=python的模块
Java的方法=python的函数

方法包含方法头和方法体:
方法头构成
修饰符:可选,告诉编译器如何调用该方法,定义了该方法的访问类型
返回值类型:方法可能有返回值,返回值的数据类型,如果没有返回值就用void
方法名
参数类型,参数也是可选的
方法体
格式
修饰符 返回值类型 方法名(参数类型 参数名){
方法体
return 返回值
}

return不单可以返回值,但为0时,就是终止程序

public class  Demo01 {
    public static void main(String[] args) {
        int result = max(10, 10);
        System.out.println("最大值:" + result);
    }

    //加法
    public static int max(int a, int b) {
        int result = 0;
        if (a == b) {
            System.out.println("两个数相等");
            return 0;//这里的return 0 是终止方法,跳出方法,不执行后续代码
        } else if (a > b) {
            result = a;
        } else {
            result = b;
        }
        return result;

    }

}

方法调用
当方法返回一个值时,就方法调用通常被当成一个值,需要用变量承载
int larger=max(30,40);
当方法返回值是void时,方法调用一定是一条语句
system.out.println()

方法的重载
重载就是在一个类中,有相同的函数名称,但形参不同的函数
规则:
1、方法名称要一样
2、参数列表要不同(个数,类型,顺序不同)
3、返回类型可以相同也可以不同
举例,调用max(),参数可以2个也可以3个,类型也可以不一样,但是要在方法定义好

命令行传参了解下就可以了

可变参数
方法声明时,指定参数类型后加一个省略号...
一个方法只能指定一个可变参数,而且是方法的最后一个参数,任何普通参数要在它之前声明

public class  Demo01 {
    public static void main(String[] args) {
        Demo01 demo = new Demo01();
        demo.test(1,2,3,4,5);// 1

    }

    public void test(int ...i){
        System.out.println(i[0]);
    }
    
}

递归
递归就是:A方法调用A方法,自己调用自己
递归结构包括两个部分:
递归头:什么时候不调用自身方法,如何没有头,将陷入死循环
递归体:什么时候需要调用自身方法

public class  Demo01 {
    public static void main(String[] args) {
        System.out.println(f(3));//数少还行,数多容易崩,递归方法以不用就不用,了解即可


    }

    public static int f(int n){
        if(n==1){
            return 1;//递归头
        }else{
            return n*f(n-1);//输入n=3时,,就是3*2*1,最后等于6//递归体
        }
    }

}

数组

数组就是相同类型数据的有序集合
数组的声明和创建

public class  Demo01 {
    public static void main(String[] args) {
        //变量类型 变量名字=变量的值
        //数组类型int[]
        //1、先声明数组变量,2、再使用new关键字创建数组,1和2可以合并3、再给数组元素赋值
        //int[] nums;//声明数组,首选,也能写成int nums[];
        int[] nums=new int[2];
        nums[0]=1;//如果没有赋值会默认0
        nums[1]=2;
        System.out.println(nums[0]);//1
    }
}

栈和堆的概念
在栈中声明数组的变量
在堆中创建数组空间,只要是用到new的,都是一个对象,数组也是对象,都是放在堆中

三种初始化
1、静态初始化
2、动态初始化
3、默认初始化

public class  Demo01 {
    public static void main(String[] args) {
        //静态初始化:创建+赋值
        int [] a={1,2,3,4,5};//可以直接初始化数组,跳过new操作
        System.out.println(a[0]);//输出数组第一个元素

        //动态初始化:包含默认初始化,就是还没赋值的元素都为0
        int[] b=new int[10];
        b[0]=10;
        System.out.println(b[0]);//10
        System.out.println(b[1]);//0
    }
}

数组的长度是确定的,不可变的,如果越界,则报ArrayIndexOutofBounds的错误提示

数组使用
1、for循环
2、for-each循环
3、数组作方法入参
4、数组作返回值
第一种方式

public class  Demo01 {
    public static void main(String[] args) {
        int [] arrays={1,2,3,4,5};
        for(int i=0;i<arrays.length;i++){
            System.out.println(arrays[i]);
        }
    }
}

第二种方式-快捷键arrays.for+ctrl&enter

public class  Demo01 {
    public static void main(String[] args) {
        int [] arrays={1,2,3,4,5};
        for (int array : arrays) {
            System.out.println(array);
        }

    }
}

第三种方式

public class  Demo01 {
    public static void main(String[] args) {
        int [] arrays={1,2,3,4,5};
        printArray(arrays);
    }
    public static void printArray(int[] arrays){
        for(int i=0;i<arrays.length;i++) {
            System.out.println(arrays[i]);
        }
    }
}

多维数组

public class  Demo01 {
    public static void main(String[] args) {
     /*
     1 2
     2 3
     3 4
     4 5
      */
        int[][] array={{1,2},{2,3},{3,4},{4,5}};
        System.out.println(array[0][0]);//1
        System.out.println(array[0][1]);//2
    }
}

arrays类讲解

public class  Demo01 {
    public static void main(String[] args) {
       int[]a={1,3,45,45,563,46,7,8,9,10};
       System.out.println(Arrays.toString(a));
       Arrays.sort(a);//排序
       System.out.println(Arrays.toString(a));//[1, 3, 7, 8, 9, 10, 45, 45, 46, 563]

    }
}

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

public class  Demo01 {
    public static void main(String[] args) {
       //冒泡排序
        //1、比较数组中,两个相邻的元素,如果第一个元素比第二数大,就交换他们的位置
        //2、每一次比较,都会产生一个最大一个最小
        //3、下一轮则可以少一次排序;
        //4、重复以上步骤,直到数组排序完成。
        int[] arr = {5, 3, 8, 6, 2, 7, 1, 4};
        sort(arr);
        System.out.println(Arrays.toString(arr));

    }
    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 - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
        return array;
    }
}

稀疏数祖

面向对象编程

1、面向对象的思路来分析整个系统,具体到微观操作,仍然需要面向过程的思路去处理
2、面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
3、抽象:就是把共同的特征抽取出来,把象的特征抽取出来
4、三大特性:
封装
继承
多态
5、从认识角度考虑先有对象后有类,对象,是具体的事物,类,是抽象的,是对对象的抽象,-也就是把相似的特征抽象成类
但从代码运行角度考虑是先有类后有对象,类是对象的模板

方法回顾
方法调用
静态方法和非静态方法的区别,有没加static的区别
有加static,另一个类调用,可以直接类加方法调用

非静态方法,需要先new一个对象出来才能用类方法

类和对象的创建
使用new关键字创建的时候,除了分配内存空间之外(参考数组的new),还会给创建好的对象进行默认初始化以及对类中构造器的调用
Student s1=new Student();
Student s1是对象引用
使用new时相当于调用了类的构造器,并走了一遍构造器后,才给s1进行赋值

构造器详解

1、构造器(可以理解为是类自带的方法)是建完类后自动生成的,通常格式是public+类名,没有返回值
2、new后,是走完一遍构造器,才生成对象。可以理解new的本质就是在调用构造器(可以用debug试下)
3、构造器,一般拿来初始化值
4、快捷键,属标右键生成,可以构造有参或无参的构造器
5、this+变量名,this表示当前类
6、如果构造器写了有参构造,那就把无参构造也一起写了,否则new的时候会报错,一般new的时候不写参数,会自动调用无参构造,如果这个时候发现类没有无参构造,就会报错,除非new的时候马上写上参数,
7、构造器分为无参构造,有参构造,默认构造(就是无参构造,里面什么方法都没有)

创建对象内存分析
栈只是放了个变量名,真正的对象是放在堆中

封装

属性私有get/set
封装一般是用于属性
生成里面有自动生成get和set的方法

public class Student {
    //属性私有
    private String name;
    private int id;
    private char sex;

    //提供可以操作这个属性的方法
    //提供一些public的get\set方法

    //get 获得这个数据
    public String getName() {
        return this.name;
    }
   //set 设置这个数据
    public void setName(String name) {
        this.name = name;
    }

    
}
package operator;
//一个项目应用只有一个main方法
public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        //s1.name//因为Student的name属性是private的,所以不能直接访问,需要通过getter方法获取
        s1.setName("Tom");
        System.out.println(s1.getName());

封装的意义,可以在类的方法中限定条件,列如年龄的限制,使用得对象赋值更加合理

封闭的意义
1、提高程序的安全性,保护数据
2、隐藏代码的实现细节
3、统一接口,只能get或set
4,系统可维护增加了

继承
extends

public class Student extends Person{
}

ctrl+H,可以快速查看继承关系

package operator;
//父类
//子类继承了父类,就会拥有父类的全部方法
public class Person {

    //public方法,如果想让子类继承父类所有东西,就得用public方法
    //private,无法被子类继承,但会通过留有的方法来实现继承功能
    public void say(){
        System.out.println("I am a person.");
    }
}
import operator.Student;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();

    }
}

JAVA中,所有的类,都默认直接或间接继承Object类
JAVA中类只有单继承,没有多继承,只有一个爸爸,但是爸爸可以有多个儿子

super详解

package operator;

public class Person {
    public Person(String name) {
        System.out.println(name);
    }

    protected String name="cjf";
    private int age=25;
}


package operator;
//派生类或叫子类
public class Student extends Person{
    public Student() {
        super("cjf");
        //有隐藏代码,调用了父类的无参构造,这个隐藏代码就是super();
        //调用父类的构造器,必须要在子类的构造器之前调用,否则会报错。无参时默认调用,不用写。除非父类有参数,就要写了.注意,父类如果是有参构造时,顺便把无参构造也写了,否则子类在调用父类的构造器时会报错,除非马上把super(参数)也写了
//this()和super()只能选一个,又不调用父类构造器,又不调用子类构造器,调完再写自身的构造器的方法,this可用于调用自身构造器的方法,列如同时写了无参和有参构造器方法,无参构造器用this调用有参构造器
        System.out.println("Student 无参执行");
    }

    //protected String name="cjfcjf";
    //public void test(String name){
        //System.out.println(name);//john
       // System.out.println(this.name);//类的方法
        //System.out.println(super.name);//父类的属性
       // System.out.println(super.age);//父类的属性加了private,就不能继承
   //}
}
import operator.Student;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();//调用构造器时,会先调用父类的构造器,然后才是子类的构造器,


        // Person 无参执行
        //Student 无参执行
        
        //有参后
        cjf
        Student 无参执行

        //student.test("John");


    }
}

super注意点
1、super调用父类的构造方法,要在构造方法的第一个,父类是无参构造方法时,子类super可以默认不写,如果父类是有参构造方法时,子类要先写super(参数),再写子类的构造方法
2、super必须只能出现现在子类的方法或者构造方法中
3、super和this不能同时调用构造方法

vs this
代表的对象不同
this 本身调用者这个对象
super代表父类对象的应用
前提
this 没继承者也可以使用
super只有继承条件才可以使用
构造方法
this()本类的构造
super()父类的构造

方法重写
方法重写都是和方法相关,和属性无关

package operator;

public class Person {
    public static void test() {
        System.out.println("person=<test()");
    }
}
package operator;
//派生类或叫子类
public class Student extends Person {
    public static void test() {
        System.out.println("Student=>test()");
    }
}
import operator.Student;
import operator.Person;
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.test();
//静态的方法和非静态的方法区别很大
        //静态方法,方法的调用只和左边,定义的数据类型有关,就是以子类和父类的方法都加了static关键字
        Person P = new Student();
        P.test();
    //Student=>test()
    //person=<test()

        //student.test("John");


    }
}

当子类和父类方法都加static时,调用的都是各自类的方法
当子类和父类方法都不加static时,调用的都是子类的方法(重写后的方法)
更多参考看这个链接https://mp.weixin.qq.com/s/N6SeN6p0UbR7a84fo64iPg

package operator;

public class Person {
    public  void test() {
        System.out.println("person=<test()");
    }
}
package operator;

public class Student extends Person {
    public  void test() {
        System.out.println("Student=>test()");
    }
}
import operator.Student;
import operator.Person;
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.test();
//静态的方法和非静态的方法区别很大
        //静态方法,方法的调用只和左边,定义的数据类型有关,就是以子类和父类的方法都加了static关键字
        Person P = new Student();
        P.test();
        //Student=>test()
        //Student=>test()


    }
}

子类重写父类方法的快捷键:右键,生成,重写方法,会自动生成

public class Student extends Person {
    @Override
    public void test() {
        super.test();
    }
}

重写:需要继承关系,子类重写父类方法
1、方法名,必须相同
2、参数列表必须相同
3、修饰符,范围可以扩大不能缩小,public>protested>Default>private
4,抛出的异常范围,可以被缩小,但不能扩大,classnotfoundexception<exceltion
重写,子类方法和父类要一致,方法体不同
为什么要重写,父类的功能,子类不一定需要,或者不一定满足

多态

package operator;
//派生类或叫子类
public class Student extends Person {
    @Override
    public void run() {
        System.out.println("学生在跑步");
    }
    public void study() {
        System.out.println("学生在学习");
    }
}
import operator.Student;
import operator.Person;
public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        Person s2 = new Student();

        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        s2.run();//学生在跑步,因为子类父类方法都去掉static修饰符了,子类方法重写了,所以s2调用的是子类的run方法
        s1.run();//学生在跑步,
        s2.study(); //报错了,因为s2是Person类型,没有study方法,对象能对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        s1.study(); //学生在学习

student能调用的方法都是自己的或者继承父类的
person父类型,可以指向子类,但是不能调用子类独有的方法

package operator;
//派生类或叫子类
public class Student extends Person {
    @Override
    public void run() {
        System.out.println("学生在跑步");
    }
    public void study() {
        System.out.println("学生在学习");
    }
}
import operator.Student;
import operator.Person;
public class Application {
    public static void main(String[] args) {
        //student能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        //person父类型,可以指向子类,但是不能调用子类独有的方法
        Person s2 = new Student();

        //对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
        s2.run();//学生在跑步,因为子类父类方法都去掉static修饰符了,子类方法重写了,所以s2调用的是子类的run方法
        s1.run();//学生在跑步,
        s2.study(); //报错了,因为s2是Person类型,没有study方法,对象能对象能执行哪些方法,主要看对象左边的类型,和右边关系不大
       s1.study(); //学生在学习
    }
}

总结,
当使用多态方式Father f1=new Son();调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
如果子类没有重写方法,那实例化后的对象,调用的方法都是父类的方法
如果子类重写了方法,那用多态方式后的f1,调用的方法都是子类的方法,但是方法不能有static,例如public void study()
person对象无法调用子类的新方法,只有student对象可以调用子类的新方法,需要使用到强制转换,也就是(Rabbit)zoo。
格式为:(类型名)变量名。

多态注意事项
1、多态是方法的多态,属性没有多态
2、父类和子类有联系,类型转换异常会报classcastexception
3、多态存在条件,缺一不可:1、继承关系,2、方法需要重写,3、父类引用指向子类对象Father f1=new Son();

标注:(3)向上转型:就是要将父类引用指向子类对象,只有这样该引用才既能调用父类的方法,又能调用子类的方法。只有满足了以上3个条件才能实现多态,开发人员也才能在同一个继承结构中,使用统一的代码实现来处理不同的对象,从而执行不同的行为。-不重写就能调用父类的方法,重写就能调用子类的方法-只看左边类型,无重写调用父类方法,有重写调用子类方法

package operator;

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

public class Student extends Person {
    @Override
    public void eat() {
        System.out.println("我是中文吃吃吃");
    }
}
import operator.Student;
import operator.Person;
public class Application {
    public static void main(String[] args) {
        Person s1 = new Student();
        s1.run();//run
        s1.eat();//我是中文吃吃吃
   }

}

哪些方法不能被重写
a,static方法,属于类,它不属于实例
b,final常量
c,private方法

instanceof和类型转换

//Object>Person>Teacher
//Object>Person>Student
Object object=new Student();
system.out.println(x instanceof Y);

system.out.println(object instanceof student);//true
system.out.println(object instanceof teacher);//false

类型转化

package operator;

public class Student extends Person {
    public void study() {
        System.out.println("I am studying.");
    }
}
import operator.Student;
import operator.Person;
public class Application {
    public static void main(String[] args) {
   //类型之间的转化:父 子
        //高                低
        Person p = new Student();//低转高,不需要强行转化
        //将这个p对象转换成Student类型,我们就可以调用Student的方法了,高转低,需要强行转化
        Student p1 = (Student) p;
        p1.study();//I am studying.也能简写成((Student) p).study();

   //子类转为父类,可能会丢失自己本来的一些方法
        Student student = new Student();
        student.study();
        Person person = student;//小转大,不需要强行转化
        person.study();-出现报错,向上转型,会丢失子类中原本可直接调用的特有方法(增加的方法)
    }

}

1、父类引用指向子类的对象
2、把子类转换成父类,向上转型
3、把父类转换成子类,向下转型,强制转换,高转低
4、方便方法的调用,减少重复的代码

总结:
1、new子类对象时,会先走子类的构造方法,但是子类构造方法中开头会有super(),所以会再走去父类的构造器,走完再回子类的构造器,最后回到new的对象

package operator;

public class Person {
    public Person() {
    }
    public Person(String name) {
        System.out.println("Hello, my name is " + name + "!");
    }
    public void say() {
        System.out.println("Hello, I am a person.");
    }
}
package operator;

public class Student extends Person {

    public Student() {
        super("Student");
        System.out.println("Student Constructor");
    }
}

2、new对象后,调用方法时,如果调用该方法子类没有的话,会去父类中调(子类继承父类的方法的原理),如果子类重写了方法,则调用该方法,会到子类调完就回来主程序了
3、Student student = new Student();

Person student2 = new Student();子类重写了方法后,两个对象调用方法走了是一样的路径,不同时前面的对象可以直接调用子类的其它方法,后面要做转化才能做转化
4、sudent2s相当于new Student了一个子类对象,然后赋值给了父类对象student2,所以stduent2可以用子类的方法,(相当于子转父,不需要强转)

package operator;

public class Person {
  public void sayHello() {
      System.out.println("Hello, I am a person.");
  }
}
package operator;

public class Student extends Person {
    public void sayHello() {
        System.out.println("Hello, I am a student.");
    }


}
import operator.Student;
import operator.Person;
public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.sayHello();//Hello, I am a student.
        Person student2 = new Student();
        student2.sayHello();//Hello, I am a student.


    }
}

static关键词详解
static是类独有的方法,只要加了,其他人就用不了,只有本类能用

package operator;

public class Student extends Person {
    private static int age;//静态的变量
    private double score;//非静态的变量

    public void run() {
    }
    public static void go() {
    }

    public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println(Student.age);//类变量
        //System.out.println(Student.score);//报错,非静态变量
        System.out.println(s1.age);//实例变量
        System.out.println(s1.score);//实例变量

        go();//可以直接调用静态方法
        Student student = new Student();
        student.run();

    }

}
package operator;

public class Person {
    {
        //代码块,(匿名代码块),在构造器之前执行
    }
    static{
        //静态代码块,(静态初始化块),在类被加载时执行一次,
        
    }
}
public class Person {
    {
        System.out.println("匿名代码块");//一般拿来赋初值
    }
    static{
        System.out.println("静态代码块");//只执行一次
    }
    public Person() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        Person p = new Person();
        //输出结果静态代码块
        //匿名代码块
        //构造方法
        Person p2 = new Person();
        //匿名代码块
        //构造方法
    }

静态导入包,了解即可,很少这么玩
用final修饰后,就不能被继承了,例如pubic final class person,

抽象类
1、抽象类不能new,只能靠子类去实现
2、抽象类可以写普通方法
3、抽象方法只能在抽象类中
package operator;
//abstract抽象类,类只能单继承

public abstract class Action {
    //约束,别人帮忙实现这个方法
    //抽象方法,只有方法名字,没有方法实现
    public abstract void doSomething() {
}
package operator;
//抽象类的方法,经过继承后,子类必须实现该方法
public class A extends Action{
    @Override
    public void doSomething() {

    }
}

接口
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有
接口:只有规范,自己无法写方法,专业的约束,约束和实现分离,面向接口编程

package operator;
//interface 定义的关键词,接口都需要有实现类
public interface UserService {
    //接口中的所有定义其实都是抽象的
//接口中所有定义的方法其实都是抽象的public abstract,只是可以省略不写
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}
package operator;
//类可以实现接口,implements 接口
//利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService {
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }
}

作用
1、约束
2、定义一些方法,让不同的人实现
3、所有的方法都是public abstract可以省略不写
4、所有的常量都是public static final
5、接口不能被实例化,接口中没有构造方法
6、imliemens可以实现多个接口
7、必须重写接口中的方法

内部类
A类中定义一个B类,那么B类相对A类来说就是内部类,A类相对B类来说就是外部类
1、成员内部类

public class Outer {
    private int id=10;
    public void out(){
        System.out.println("这是外部类的方法" );
    }
    public class Inner{
            public void in(){
            System.out.println("这是内部类的方法" );
            }
            //获得外部类的私有属性/方法,这是内部类才能做到的
            public void getId() {
                System.out.println(id);
            }
    }
}
package operator;

public class Application {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.getId();

    }
}

2、静态内部类
就是内部类加上static
内部类可访问static,但是static的内部类不能访问外部非静态的属性

package operator;

public class Outer {

}
//一个java类可以有多个class 类,但是只能有一个目标public class
class A{
    //可以拿来做测试写main方法
}

3、局部内部类

package operator;

public class Outer {
    
    // 局部内部类
    public void method() {
        class Inner {
            public void innerMethod() {
        }
    }
}

4、匿名内部类

package operator;

public class Outer {
    public static void main(String[] args) {
        //没有名字的初始化类,不用实例保存到变量中
        new Inner().method();
        new UserService() {
            @Override
            public void hello() {
                
            }
        }
    }
    
}
class Inner {
    public void method() {
        System.out.println("Inner method");
    }
}
interface UserService {
    void hello();
}

异常机制
Exception例外,就是异常
文件找不到,网络连接失败,非法参数等等
三种异常
1、检查性异常
2、运行时异常
3、错误error(大部分错误和程序无关)
Exception一般是程序逻辑错误引起(可能编译都无法通过)
error通常是灾难性的,程序无法控制 ,遇到这些情况时,JVM会直接终止进程,Exception通常可以被程序处理,并且在程序中尽可能去处理这些异常

异常:捕获和抛出异常
try catch finally,throw,throws

package operator;

public class Test {
    public static void main(String[] args) {
        int a=1;
        int b=0;
        try {//try监控区域
            System.out.println(a / b);
        }catch(ArithmeticException e) {//出现这个异常,就会执行catch块,可以写最大的异常处理,也可以写好几个catch,一般把最大的异常放在最后一个
            System.out.println("程序出现 异常");
        }finally {//无论是否出现异常,都会执行finally块
            System.out.println("程序执行结束");
            }
        //finally 可以不用,假设IO,资源关闭,善后工作
    }
}

ctrl+Alt+t,快捷键
throw用法

package operator;

public class Test {
    public static void main(String[] args) {
        try {
            new Test().test(10, 0);
        } catch (ArithmeticException e) {
            e.printStackTrace();//主动抛出异常,显示Cannot divide by zero,程序终止
        }

    }
    //假设这方法中,处理不了异常,方法上抛出
    public void test(int a, int b) throws ArithmeticException {
        if(b==0){
            throw new ArithmeticException("Cannot divide by zero");//主动抛出异常,一般在方法中使用
        }
    }
}

自定义异常
用户可以自定义类,只需继承Exception类即可
双击shift打开搜索功能
参考throw的用法

总结
1、处理异常时,采用try catch处理
2、多重catch,可以加一个catch(Exception)来处理可能会遗漏的异常
3、尽量添加finally语句去释放占用的资源

最后总结补充

1、数据类型分为基础类型和引用类型
基础类型:整数(byte\int\short\long),浮点数(float\double),字符(char),布尔(boolean)共8种
引用类型:类、接口、数组

2、大部分引用类型都是需要通过new才行,走内部的构造方法,除了像String等比较特殊,可以直接赋值
引用类型就是类的类型,例如Stduent,所有的对象都是引用类型,包括数组对象。引用类型必须使用new调用构造方法进行赋值,引用类型的变量(对象引用)拥有自己的属性和方法,
数组和列表不一样,数组里面的类型要一样,列表可以不一样

3、Car myCar = new Car();
左边:Car就是引用类型,myCar就是对象引用,
右边:就是对象,被new出来的对象
在堆中创建一个对象,然后引用赋值给myCar,mycar变量在栈中,
这行代码会在内存中创建一个新的Car对象,并将它的引用赋值给myCar。创建对象后,可以通过点操作符(.)来访问对象的属性和方法:

4、引用类型和对象的关系‌主要体现在引用类型用于存储对象的引用,而不是对象本身。引用类型变量(对象引用)存储的是对象在内存中的地址,通过这个地址可以间接访问和操作对象。
引用类型是一种数据类型,用于存储对象引用(或称为句柄)。当声明一个引用类型的变量时,该变量并不直接存储对象本身,而是存储了一个指向对象在内存中位置的地址。这意味着通过引用类型的变量,可以间接地操作对象‌,(不像基本类型,变量直接存储值)

定义和创建‌:对象是类的实例,而对象引用是用于指向这些对象的变量。例如,在Java中,Person person = new Person("张三"); 这行代码创建了一个Person类的对象(右边),而person就是一个对象引用,它指向这个新创建的对象‌
关系‌:一个对象可以被一个或多个对象引用所引用,而一个对象引用可以指向零个或一个对象。这种关系类似于一夫多妻制,一个丈夫(对象)可以有多个妻子(对象引用),而一个妻子(对象引用)只能有一个丈夫(指向一个对象)‌
区别‌:引用类型变量存储的是对象的地址,而对象本身是类的实例。例如,在Java中,Person person; 这行代码声明了一个引用类型变量person,但它并没有指向任何对象。只有通过person = new Person("张三"); 这行代码,person才真正指向了一个新创建的对象‌
联系‌:通过引用类型的变量,可以间接访问和操作对象。例如,可以通过person.name或person["name"]来访问对象的属性‌

4、基本数据类型保存在栈里面,可以直接访问它的值,引用数据类型保存在堆里面,栈里面保存的是地址,通过栈里面的地址去访问堆里面的值
栈和堆文章参考https://zhuanlan.zhihu.com/p/28654272

5、命名规范:
类,StudnetOne
变量和方法:teacherOne
常量:STUDENT_ONE

6,a\同一个包的类不需要import,可以直接类名+方式或new
b\如果类中的属性或方法加上了static,那像主程序引入类时,可以直接类名+方法,或类名+属性,没加static,只能通过new了对象,再通过对象使用方法或属性,可以理解加了staic后,方法和属性就是类独有的-只是会很少这样用
c\static是类独有的方法,只要加了,其他人就用不了,只有本类能用,继承时父类的方法不能用static,不然子类重写不了方法

7、什么时候可以定义静态变量?当类中出现所有对象都共有的数据时,该字段就可以定义成静态的。比如刚才说的学生类里的国家这个字段就可以定义成静态的
什么时候可以定义静态方法?当方法内部没有使用到非静态数据(对象的特有数据)时,那么该方法就可以定义成静态的大家平常见到的工具类 XxxUtils就很符合上边的场景,所以大家见到的工具类基本上都是静态的,不用new对象,直接XxxUtils.xxx()调用
3、静态的其他内容理解 理解了上述内容后,下边的内容就不难理解了静态:static关键字static关键字的用法:它是一个修饰符,用于修饰成员(成员变量,成员方法)静态的特点:1、随着类的加载而加载(就是说这个类一被加载进内存,静态的东西就随着加载进去了, 这时候对象还不存在呢)2、静态先于对象存在3、被所有的对象共享4、可以直接被类名调用,也可以被对象调用
静态使用的注意事项:1、静态方法只能访问静态成员(属性和方法),不能访问非静态成员。因为静态在的时候非静态的还没在呢2、非静态方法可以访问静态成员,也可以访问非静态成员3、因为静态先于对象的存在而存在,所以静态方法中不可以出现this、super关键字。
静态的利弊:1、利:对于所有对象都共有的数据,没必要每个对象中都存在一份,可以使用静态,节省空间;可以不new对象,直接用类名调用2、弊:因为静态是随着类存在的,所以生命周期过长;访问出现局限性,只能访问静态
https://mp.weixin.qq.com/s/-_HERFTyMiAkv0wQ--RXqA

posted @   乘加法  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示