java笔记

前言

尚硅谷B站公开课学习笔记

第一天

基础格式部分

  1. java程序编写-编译-运行的过程
    编写:我们将编写的java代码保存在以".java"结尾的源文件中
    编译:使用javac.exe命令编译我们的java源文件。格式:javac 源文件名.java
    运行:使用java.exe命令解释运行我们的字节码文件。 格式:java 类名

  2. 在一个java源文件中可以声明多个class。但是,只能最多有一个类声明为public的。
    而且要求声明为public的类的类名必须与源文件名相同。
    文件名是Main.java那么public就只能加到Main类前面。

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

  1. 程序的入口是main()方法。格式是固定的。

  2. 输出语句:
    System.out.println():先输出数据,然后换行
    System.out.print():只输出数据

  3. 每一行执行语句都以";"结束。

  4. 编译的过程:编译以后,会生成一个或多个字节码文件。字节码文件的文件名与java源文件中的类名相同。只能运行包含main方法的类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fSK76nvJ-1673872752650)(C:\Users\liu\Desktop\1.png)]

如图所示,红色箭头所指的名字要相同,当然可以不是Main,但要相同,并且public只能加在它前面。(注意,这并不是说只有它可以运行)

蓝色箭头所指的是另一个类,它不能加public,因为已经有人加了。

并且值得注意的是,一个类只有包含了main方法才可以执行,

变量与运算符

关键字和保留字

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

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

标识符

凡是可以自己起名字的地方都叫标识符,类名、变量名、方法名、接口名……

标识符有自己的命名规则,和C差不多,不过多了个$可以用,还是数字不能开头

变量

变量类型、变量名、存储的值,和C一样的

多了个byte,这样就能1、2、4、8了

注意!声明long型变量必须以"l"或"L"结尾
注意!声明float型变量必须以"f" 或"F"结尾

long l1=31415926L;

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

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

第二天

Java学习的三条主线

在这里插入图片描述

封装性

在这里插入图片描述
加public表示是全局类,这个public类可以被所有类调用,即可以import导包到任何类中;
其余的没加public的表示保留类,只能被本包中的其他类调用。

类的内部成员可以使用四种权限修饰符修饰

构造器

在这里插入图片描述
在这里插入图片描述

此处的People()就是一个无参构造器,任何类都会有一个构造器,包括抽象类

构造器主要有两个作用
1.搭配new关键字,创建类的对象
2.在创建对象的同时,可以给对象的相关属性赋值

构造器的使用说明
1.构造器声明的格式:权限修饰符 类名(形参列表){ }
2.创建类以后,在没有显示提供任何构造器的情况下,系统会默认提供一个空参的构造器,且构造器的权限与类声明的权限相同
3.一旦类中显示声明了构造器,则系统不再提供默认的空参构造器
4.可以声明多个构造器,彼此之间构成重载关系
5.注意:构造器不是方法,它和方法没关系

实例变量与类变量

public class UserTest {
    public static void main(String[] args) {
        //实例变量,每一个对象都有一份
        User u1 = new User();
        User u2 = new User();
        //后面有加static修饰的静态变量(类变量)
        //类变量是每个对象共用的
    }
}

class User{
    //属性(或实例变量)
    //实例,就是对象
    //实例变量,就是这两个变量归于具体的对象所有
    String name;
    int age;
}

/**
 * 一、类中属性(当前仅考虑实例变量)赋值过程
 * 1.在类的属性中,有哪些位置可以给属性赋值?
 * ①默认赋值 ②显式赋值 ③构造器中赋值
 * ④通过“对象.方法”赋值 ⑤通过“对象.属性”的方法赋值
 * 2.这些位置执行的先后顺序是怎样的?
 * ① - ② - ③ - ④/⑤
 * 其中①、②、③只能执行一次,④、⑤可以执行多次
 */

class moren{//默认赋值
    int a;
}
class xianshi{//显式赋值
    int a = 5;
}
class gouzao{//构造器中赋值
    int b;
    gouzao(int b){
        this.b = b;
    }
}

实例方法与类方法

在Java中,函数要加上static关键字才能被称为静态方法(static method)。这是因为Java中的方法分为两种类型:实例方法(instance method)和静态方法(static method)。

  1. 实例方法(非静态方法):
    实例方法是与对象实例相关联的方法,也就是说,只有在创建类的对象后才能调用这些方法。在实例方法内部,可以访问和操作对象的实例变量。实例方法是非静态方法,因为它们依赖于类的实例存在。

  2. 静态方法:
    静态方法不与任何对象实例相关联,它们属于整个类而不是类的实例。静态方法在类加载时就已经存在,并且可以直接通过类名调用,不需要创建类的对象。由于静态方法不依赖于实例变量,所以在静态方法内部不能直接访问实例变量。

为了在Java中调用一个方法,必须先通过类创建一个对象,然后通过对象调用实例方法。但是,如果一个方法在执行过程中不需要访问实例变量,或者不依赖于类的实例状态,那么就可以将该方法声明为静态方法,从而避免创建对象的开销,并且可以直接通过类名调用。

例子:

public class MyClass {
    // 静态方法
    public static void staticMethod() {
        // 可以在静态方法中调用其他的静态方法
    }
    
    // 实例方法
    public void instanceMethod() {
        // 可以在实例方法中调用其他实例方法以及静态方法
    }
}

可以不加static吗?
答案是可以的,但这取决于你的需求。如果方法需要访问实例变量或者与对象的状态相关,那么它必须声明为实例方法,此时不能加static关键字。如果方法不需要访问实例变量或者与对象状态无关,那么可以将其声明为静态方法,并在方法名前加上static关键字。

总结:

  • 静态方法不依赖于类的实例,可以直接通过类名调用。
  • 实例方法依赖于类的实例,需要先创建类的对象才能调用。

this的使用

/**
 * this关键字的使用
 * 1.使用形参num给属性num赋值时,this.num代表属性,num代表形参
 * 2.this可以调用成员变量、方法、构造器,不能调用局部变量
 * 3.this指的是当前对象(在方法中调用时)或当前正在创建的对象(在构造器中调用)
 * this调用属性和方法
 * 针对方法内的使用情况(准确的说是非static修饰的方法)
 * 一般情况:通过对象调用方法,可以在方法内调用当前对象的属性或其他方法,我们可以在前面加this.但是一般情况下我们会省略
 * 特殊情况:如果方法的形参和对象的属性同名了,那么要用this.来指明哪个是对象的属性
 * 针对构造器内的使用情况,我们可以在类的构造器中,调用当前类中指定的其它构造器,注意,调用其他构造器的语句必须声明在当前构造器的首行
 * 在一个构造器中,最多有一个this(形参)
 * 如果一个类中声明了n个构造器,则最多有n-1个构造器中有this(形参)
 */
public class this_user {
    String name;
    int age;
    public this_user(){
        //模拟对象创建时,需要初始化50行代码
    }
    public this_user(String name){
        this();
        //直接使用this()代表调用当前对象的空参构造器
        //注意不要携程this_user()了,也没有this.this_user()
        this.name = name;
    }
    public this_user(String name,int age){
        this(name);
        //也可以使用this(参数)来调用当前对象的带参构造器
        this.age = age;
    }
}

第三天

第一个案例

package day03.exer3;


import java.util.Scanner;

/**
* CMUtility工具类:
* 将不同的功能封装为方法,就是可以直接通过调用方法使用它的功能,而无需考虑具体的功能实现细节。
*
* @author 尚硅谷-宋红康
* @create 17:17
*/
public class CMUtility {
    private static Scanner scanner = new Scanner(System.in);
    /**
	用于界面菜单的选择。该方法读取键盘,如果用户键入’1’-’5’中的任意字符,则方法返回。返回值为用户键入字符。
	*/
	public static char readMenuSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false);
            c = str.charAt(0);
            if (c != '1' && c != '2' && 
                c != '3' && c != '4' && c != '5') {
                System.out.print("选择错误,请重新输入:");
            } else break;
        }
        return c;
    }
	/**
	从键盘读取一个字符,并将其作为方法的返回值。
	*/
    public static char readChar() {
        String str = readKeyBoard(1, false);
        return str.charAt(0);
    }
	/**
	从键盘读取一个字符,并将其作为方法的返回值。
	如果用户不输入字符而直接回车,方法将以defaultValue 作为返回值。
	*/
    public static char readChar(char defaultValue) {
        String str = readKeyBoard(1, true);
        return (str.length() == 0) ? defaultValue : str.charAt(0);
    }
	/**
	从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
	*/
    public static int readInt() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(2, false);
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }
	/**
	从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
	如果用户不输入字符而直接回车,方法将以defaultValue 作为返回值。
	*/
    public static int readInt(int defaultValue) {
        int n;
        for (; ; ) {
            String str = readKeyBoard(2, true);
            if (str.equals("")) {
                return defaultValue;
            }

            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("数字输入错误,请重新输入:");
            }
        }
        return n;
    }
	/**
	从键盘读取一个长度不超过limit的字符串,并将其作为方法的返回值。
	*/
    public static String readString(int limit) {
        return readKeyBoard(limit, false);
    }
	/**
	从键盘读取一个长度不超过limit的字符串,并将其作为方法的返回值。
	如果用户不输入字符而直接回车,方法将以defaultValue 作为返回值。
	*/
    public static String readString(int limit, String defaultValue) {
        String str = readKeyBoard(limit, true);
        return str.equals("")? defaultValue : str;
    }
	/**
	用于确认选择的输入。该方法从键盘读取‘Y’或’N’,并将其作为方法的返回值。
	*/
    public static char readConfirmSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false).toUpperCase();
            c = str.charAt(0);
            if (c == 'Y' || c == 'N') {
                break;
            } else {
                System.out.print("选择错误,请重新输入:");
            }
        }
        return c;
    }

    private static String readKeyBoard(int limit, boolean blankReturn) {
        String line = "";

        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            if (line.length() == 0) {
                if (blankReturn) return line;
                else continue;
            }

            if (line.length() < 1 || line.length() > limit) {
                System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
                continue;
            }
            break;
        }

        return line;
    }
}

package day03.exer3;

public class Customer {
    private String name;
    private char gender;
    private int age;
    private String phone;
    private String email;

    public Customer() {

    }

    public Customer(String name, char gender, int age, String phone) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.phone = phone;
    }

    public Customer(String name, char gender, int age, String phone, String email) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.phone = phone;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

package day03.exer3;

public class CustomerList {
    private Customer[] customers;
    private int total = 0;
    public CustomerList(int totalCustomer){
        customers = new Customer[totalCustomer];
    }
    public boolean addCustomer(Customer customer){
        if(total<customers.length-1){
            customers[total++] = customer;
            return true;
        }else{
            return false;
        }
    }
    public boolean replaceCustomer(int index, Customer cust){
        if(index>=0 && index<total){
            customers[index] = cust;
            return true;
        }else{
            System.out.println("插入位置非法");
            return false;
        }
    }
    public boolean deleteCustomer(int index){
        if(index>=0 && index<total){
            for(int i=index;i<total;i++){
                customers[i] = customers[i+1];
            }
            total--;
            return true;
        }else{
            System.out.println("删除位置非法");
            return false;
        }
    }
    public Customer[] getAllCustomers(){
        return customers;
    }
    public Customer getCustomer(int index){
        return customers[index];
    }
    public int getTotal(){
        return total;
    }
}

package day03.exer3;

import static day03.exer3.CMUtility.*;

public class CustomerView {
    CustomerList customerList = new CustomerList(10);
    public void enterMainMenu(){
        boolean loopFlag = true;
        String mainView = """
                -----------------拼电商客户管理系统-----------------
                              
                                 1 添 加 客 户
                                 2 修 改 客 户
                                 3 删 除 客 户
                                 4 客 户 列 表
                                 5 结 束 操 作
                   
                                 请选择(1-5):
                                
                """;
        System.out.println(mainView);
        char choice;
        while (loopFlag){
            choice = readMenuSelection();
            if(choice == '1'){
                addNewCustomer();
                System.out.println(mainView);
            }
            if(choice == '2'){
                modifyCustomer();
                System.out.println(mainView);
            }
            if(choice == '3'){
                deleteCustomer();
                System.out.println(mainView);
            }
            if(choice == '4'){
                listAllCustomers();
                System.out.println(mainView);
            }
            if(choice == '5'){
                loopFlag = false;
            }
        }
    }
    private void addNewCustomer(){
        String name;
        char sex;
        int age;
        String number;
        String email;
        System.out.println("---------------------添加客户---------------------\n");
        System.out.println("姓名:");
        name = readString(30,"?");
        System.out.println("性别:");
        sex = readChar('?');
        System.out.println("年龄:");
        age = readInt(-1);
        System.out.println("电话:");
        number = readString(30,"?");
        System.out.println("邮箱:");
        email = readString(30,"?");
        if(customerList.addCustomer(new Customer(name,sex,age,number,email))){
            System.out.println("---------------------添加完成---------------------\n");
        }else {
            System.out.println("-----------------超出容量,添加失败-----------------\n");
        }
    }
    private void modifyCustomer(){
        System.out.println("---------------------修改客户---------------------");
        System.out.println("请选择待修改客户编号(-1退出):");
        int choice = readInt();
        if(choice != -1){
            if(choice<0 || choice>=customerList.getTotal()){
                System.out.println("---------------------无该用户---------------------");
            }else{
                Customer customer = customerList.getCustomer(choice);
                System.out.println("----------各项修改过程中直接回车表示不修改此项----------");
                System.out.println("姓名("+customer.getName()+"):");
                String name = readString(30,"-1");
                if(!name.equals("-1")){
                   customer.setName(name);
                }
                System.out.println("性别("+customer.getGender()+"):");
                char sex = readChar('\n');
                if(sex!='\n'){
                    customer.setGender(sex);
                }
                System.out.println("年龄("+customer.getAge()+"):");
                int age = readInt(-1);
                if(age != -1){
                    customer.setAge(age);
                }
                System.out.println("电话("+customer.getPhone()+"):");
                String number = readString(30,"\n");
                if(!number.equals("\n")){
                    customer.setPhone(number);
                }
                System.out.println("邮箱("+customer.getEmail()+"):");
                String email = readString(30,"\n");
                if(!number.equals("\n")){
                    customer.setEmail(number);
                }
                System.out.println("---------------------修改完成---------------------");
            }
        }
    }
    private void deleteCustomer(){
        System.out.println("---------------------删除客户---------------------");
        System.out.println("请选择待删除客户编号(-1退出):");
        int choice = readInt();
        if(choice != -1){
            if(choice<0 || choice>=customerList.getTotal()){
                System.out.println("---------------------无此用户---------------------");
            }else{
                System.out.println("确认是否删除(Y/N):");
                char choice1 = readConfirmSelection();
                if(choice1 == 'Y'){
                    customerList.deleteCustomer(choice);
                    System.out.println("---------------------删除完成---------------------");
                }else{
                    System.out.println("---------------------取消成功---------------------");
                }
            }
        }
    }
    private void listAllCustomers(){
        System.out.println("---------------------------客户列表---------------------------\n");
        System.out.println("编号\t姓名\t性别\t年龄\t电话\t\t邮箱");
        for(int i = 0;i<customerList.getTotal();i++){
            Customer customer = customerList.getCustomer(i);
            System.out.println(i+1+"\t"+customer.getName()+"\t"+customer.getGender()+"\t"+customer.getAge()+"\t"+customer.getPhone()+"\t\t"+customer.getEmail());
        }
        System.out.println("-------------------------客户列表完成-------------------------\n");
    }
    public static void main(String[] args){
        CustomerView customerView = new CustomerView();
        customerView.enterMainMenu();
    }

}

三大特性之继承性

package day04;

/**
 * 继承
 * 1.从上而下的继承,人---教师、学生
 * 2.从下而上的继承,猫、狗---动物
 * is-a的关系
 * 继承描述事物之间的所属关系,它让类与类之间产生了is-a的关系,为多态的使用提供了前提
 * 要注意这种is-a的含义,比如dog is a annimal,而不是dog is a cat
 */
public class jicheng_1 {
}
class A{
    int a;
}
class B extends A{

}

package day04;

class ManKind{
    private int sex;
    private int salary;
    public ManKind(){

    }
    public ManKind(int sex, int salary) {
        this.sex = sex;
        this.salary = salary;
    }

    void ManOrWoman(){
        if(sex == 1){
            System.out.println("man");
        }else if (sex == 0) {
            System.out.println("woman");
        }else{
            System.out.println("无性别");
        }
    }
    void employeed(){
        if(salary != 0){
            System.out.println("有工作");
        }else{
            System.out.println("没工作");
        }
    }
}

class Kids extends ManKind{

    private int yearsOld;
    //子类构造器第一句必须是super(参数/无参)
    //同时,子类本身的构造器也可以因为参数而进行重载
    //二者结合,有很多种可能,以下列举了四个可能的子类构造器
    public Kids(int age){
        super();
        this.yearsOld = age;
    }
    public Kids(int sex, int salary) {
        super(sex, salary);
    }
    public Kids(int sex, int salary,int age) {
        super(sex, salary);
        this.yearsOld = age;
    }
//    public Kids(int sex, int salary,int age) {//错误写法
//        this.yearsOld = age;
//        //Call to 'super()' must be first statement in constructor body
//        super(sex, salary);
//    }
    void printAge(){
        System.out.println(yearsOld);
    }
}

1.有了继承性以后:
> 子类就获取到了父类中声明的所有的属性和方法
> 但是由于封装性的存在,子类可能不能直接调用父类中声明的属性或方法
> 子类在继承父类以后,还可以扩展自己特有的功能,比如增加特有的属性、方法

2.关于构造方法
> 只有子类构造可以调用父类构造,普通子类方法无法调用构造器
> 子类构造方法中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造
> 子类构造可以通过super(参数)来调用父类重载构造
> super的父类构造调用,必须是子类构造方法的第一个语句,并且不能一个子类构造调用多次super构造
> 总之,子类必须调用父类构造方法,不写则赠送隐含super(),写了就用写的那个super
> super只能有一个,而且必须是第一个
class Kids extends ManKind{

    private int yearsOld;
    //子类构造器第一句必须是super(参数/无参)
    //同时,子类本身的构造器也可以因为参数而进行重载
    //二者结合,有很多种可能,以下列举了四个可能的子类构造器
    public Kids(int age){
        super();
        this.yearsOld = age;
    }
    public Kids(int sex, int salary) {
        super(sex, salary);
    }
    public Kids(int sex, int salary,int age) {
        super(sex, salary);
        this.yearsOld = age;
    }
//    public Kids(int sex, int salary,int age) {//错误写法
//        this.yearsOld = age;
//        //Call to 'super()' must be first statement in constructor body
//        super(sex, salary);
//    }
    void printAge(){
        System.out.println(yearsOld);
    }
}

3.默认的父类
Java中声明的类,如果没有显式的声明其父类时,则默认继承于java.lang.Object

4.Java支持多层继承,但是一个子类不能继承多个父类

5.四种权限修饰
修饰符         本类内部    本包内     其他包的子类      其他包的非子类
---------------------------------------------------------------
private         √         ×           ×                ×
缺省             √         √           ×                ×
protected       √         √           √                ×
public          √         √           √                √
外部类用public、缺省修饰
成员变量、方法、构造器、内部类用publicprotected、缺省、private修饰

6.关于importpublic表示是全局类,这个public类可以被所有类调用,
即可以import导包到任何类中,包括其它包中的类
其余的没加public的表示保留类,只能被本包中的其他类调用,
并且,调用同一个包里的类不用import,但是如果
包里还有子包,子包里有一个类和包里的类重名,那么要写全名称
其他包里要是有重名也可以用这个方法
继承其他包下的类时也需要导包,然而缺省类没法导到其他包的类中,
所以不能继承其他包中的缺省类
import的时候可以导高一些的包,方便用xx.xx.xx
public class ExtendTest {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "tony";
        p1.age =18;
        Person p2 = new Person();
        day04.exer2.Person p3 = new day04.exer2.Person();
        Student s1 = new Student();
        s1.name = "tony";
    }
}

二、方法的重写(override)

1.为什么需要方法的重写?
子类在继承父类以后,就获取了父类中声明的所有方法。但是,父类中的方法可能不太适用于子类,换句话说,子类需要对父类继承过来的方法进行覆盖、覆写的操作

2.方法重写的规则
[复习] 方法声明的格式:权限修饰符 返回值类型 方法名(形参列表) { //方法体 }
具体规则:
① 父类被重写的方法与子类重写的方法,方法名和形参列表必修相同。(只有这样,系统才能判断出重写的是哪一种方法)
② 权限修饰符可以不同,子类重写的方法的权限修饰符,不小于父类被重写的方法的权限修饰符。(比如父类缺省、子类public)
-- 特例:子类不能重写父类中权限为private的方法,哪怕满足方法名、形参相同,此时也会视为是子类创建的新方法,不会覆盖父类原本的方法
③ 关于返回值类型:
  > 父类被重写的方法返回值类型是引用数据类型,则子类重写的方法的返回值类型要“小于等于”父类的
  > “小于等于”:与父类返回值类型相同,或者是父类返回值的子类
  > 父类被重写的方法返回值类型是其他的,则子类重写的方法的返回值类型必须和父类一样

3.方法的重载,名字必须相同,参数列表必须不同,返回值可以不同,方法体可以不同,同一个类,多个版本一起使用
  方法的重写:名字必须相同,参数列表必须相同,返回值类型有规则,方法体可以不同,不同的类,覆盖、替换父类的方法



super关键字的使用

super和this差不多

一、super关键字的使用

1.为什么需要super?
举例1:子类继承父类之后,对父类的方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用?
举例2:子类继承父类以后,发现子类和父类中定义了同名的属性,是否可以在子类中区分两个同名的属性?(注意,属性是不会重写的)如何调用?

2.super的理解:父类的

3.super可以调用的结构:属性、方法、构造器,和this比较像
3.1 super调用属性、方法
子类继承父类后,我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法。(满足封装性的前提下)
如何调用呢?需要使用“super.”结构,表示调用父类的属性或方法
一般情况下,我们可以考虑省略“super.”的结构,但是,如果出现子类重写了父类的方法或子父类中出现了同名的属性时,则必须使用“super.”的声明,显式的调用
父类被重写的方法或父类中声明的同名的属性。(在实际开发中一定要避开这种同名的状况,不要自找麻烦)

3.2 super调用父类构造器
> 只有子类构造可以调用父类构造,普通子类方法无法调用构造器
> 子类构造方法中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造
> 子类构造可以通过super(参数)来调用父类重载构造
> super的父类构造调用,必须是子类构造方法的第一个语句,并且不能一个子类构造调用多次super构造
> 总之,子类必须调用父类构造方法,不写则赠送隐含super(),写了就用写的那个super
> super只能有一个,而且必须是第一个
class Kids extends ManKind{

    private int yearsOld;
    //子类构造器第一句必须是super(参数/无参)
    //同时,子类本身的构造器也可以因为参数而进行重载
    //二者结合,有很多种可能,以下列举了四个可能的子类构造器
    public Kids(int age){
        super();
        this.yearsOld = age;
    }
    public Kids(int sex, int salary) {
        super(sex, salary);
    }
    public Kids(int sex, int salary,int age) {
        super(sex, salary);
        this.yearsOld = age;
    }
//    public Kids(int sex, int salary,int age) {//错误写法
//        this.yearsOld = age;
//        //Call to 'super()' must be first statement in constructor body
//        super(sex, salary);
//    }
    void printAge(){
        System.out.println(yearsOld);
    }
}

三大特性之多态性

请添加图片描述

请添加图片描述
请添加图片描述

什么是多态?

package day05.duotai;

public class Person {
    int name;
    int age;
    int gender;
    void love(){
        System.out.println("我的爱好是爱好");
    }
}
package day05.duotai;

public class Man extends Person{
    @Override
    void love(){
        System.out.println("我喜欢钓鱼");
    }
}

package day05.duotai;

public class Woman extends Person{
    @Override
    void love(){
        System.out.println("我喜欢逛街");
    }
}

package day05.duotai;

public class duotai_test {
    public static void main(String[] args) {
        Person human1 = new Man();
        Person human2 = new Woman();
        human1.love();
        human2.love();
        System.out.println(human1);
    }
}

以上四段代码,分别是Person类的定义以及它的两个子类Man和Woman的定义。
其中,我们在Person类中设立了爱好(love)方法,但是出于实际考虑,每个人的爱好都是不同的,我们不可能根据每个人去设立这个方法。当然,你可以说,只要传一个参数就好了,修改一下输出的语句,但是这样做并不是一个长远的方法。引用多态的作用便是,哪怕增加了新的子类,原本父类的方法也无需改变(不用为每个子类去写一个专属于它的“爱好”方法)
多态的前提是类的继承以及子类中对父类方法的重写,将父类的引用指向子类的对象,那么一个引用类型的变量就可能指向多种不同类型的对象,父类中的爱好方法,也会变成各个子类的爱好方法
记住,编译看左边,执行看右边。(编译)声明它的类型是什么,它就拥有什么类型的属性和方法(不能直接用子类拓展出的方法)。通过它执行方法时,哪怕他声明的是Person类,执行的也是子类(Man or Woman)重写过的方法,而且它在执行语句时,实际上也是子类
注意,属性是不会被覆盖的,也就是说,当Person human1 = new Man时,输出human1的名字name,打印的将会是Person类中的默认属性值。当然,我们在继承时提到过,不提倡子类有和父类重名的属性。

向下转型与instanceof关键字的使用

package day05.duotai;

public class duotai_test {
    public static void main(String[] args) {
        Person human1 = new Man(); //此时human1被编译器识别为Person类
        //human1.earnMoney();  不能直接调用子类特有的结构
        //System.out.println(human1.isSmoking);
        Man m1 = (Man)human1; //向下转型,使用强转符
        m1.earnMoney(); //此时m1被编译器识别为Man类
        System.out.println(human1 == m1); //二者指向同一空间
        /**
         * Person p2 = new Woman();
         * Man m2 = (Man)p2;
         * 这两句代码,编译是不会报错的,但是执行时会报错
         * 编译时,编译器会看左边,认为p2是Person类,所以第二句可以强制转换
         * 执行时,编译器会看右边,发现p2实际上是Woman类,不能转换成Man类,他们之间没有父子关系
         */
        //instanceof关键字的使用
        /**
         * public class grammer {
         *         public static void main(String[] args) {
         *             Pet[] pets = new Pet[2];
         *             pets[0] = new Dog();//多态引用
         *             pets[0].setNickname("小白");
         *             pets[1] = new Cat();//多态引用
         *             pets[1].setNickname("雪球");
         *             for (int i = 0; i < pets.length; i++) {
         *                 pets[i].eat();
         *                 if(pets[i] instanceof Dog){
         *                     Dog dog = (Dog) pets[i];
         *                     dog.watchHouse();
         *                 }else if(pets[i] instanceof Cat){
         *                     Cat cat = (Cat) pets[i];
         *                     cat.catchMouse();
         *                 }
         *             }
         *         }
         * }
         */
    }
}

作业

package day05.exer2;

public class GemometricObject {
    protected String color;
    protected double weight;

    protected GemometricObject(String color, double weight) {
        this.color = color;
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public double getWeight() {
        return weight;
    }

    public void setWeight(double weight) {
        this.weight = weight;
    }

    public double findArea(){
        return 0;
    }
}

package day05.exer2;

import static java.lang.Math.PI;
import static java.lang.Math.max;

public class Circle extends GemometricObject{
    private double radius;

    public Circle(String color, double weight, double radius) {
        super(color, weight);
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    @Override
    public double findArea() {
        return Math.pow(radius,2)*PI;
    }
}

package day05.exer2;

public class MyRectangle extends GemometricObject{
    private double width;
    private double height;
    public MyRectangle(String color, double weight, double width, double height) {
        super(color, weight);
        this.width = width;
        this.height = height;
    }
    public double getWidth() {
        return width;
    }
    public void setWidth(double width) {
        this.width = width;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }

    @Override
    public double findArea() {
        return width*height;
    }
}

package day05.exer2;

public class GeometricTest {
    public static void main(String[] args) {
        Circle c1 = new Circle("blue",3,3);
        Circle c2 = new Circle("red",3,3);
        System.out.println(equalsArea(c1,c2));
        System.out.println(displayGeometricObject(c1));
    }
    public static int equalsArea(GemometricObject g1,GemometricObject g2){
        if(g1 != null && g2 != null){
            if(g1.findArea() == g2.findArea()){
                return 1;
            }else{
                return 0;
            }
        }else{
            System.out.println("请勿传入空指针");
            return 0;
        }
    }
    public static double displayGeometricObject(GemometricObject g1){
        return g1.findArea();
    }
}

第四天

接口

package day11.apply;

/**
 * @BelongsProject: untitled2
 * @BelongsPackage: day11.apply
 * @Author: Liuruij
 * @CreateTime: 2023-09-22  21:27
 * @Description: 接口的多态性
 * @Version: 1.0
 */
public class USBTest {
    public static void main(String[] args) {
        //1.创建 接口实现类 的 对象
        Computer computer = new Computer();
        Printer printer = new Printer();
        //此处调用方法时就利用了多态性
        //方法说要USB对象,传给方法的是实现了USB接口的打印机对象
        computer.transferData(printer);

        //2.创建 接口实现类 的 匿名对象
        computer.transferData(new Camera());

        //3.创建 接口匿名实现类 的 对象
        USB usb1 = new USB(){
            @Override
            public void start(){
                System.out.println("U盘开始工作");
            }

            @Override
            public void stop() {
                System.out.println("U盘工作完成");
            }
        };
        computer.transferData(usb1);
        //4.创建 接口匿名实现类 的 匿名对象
        computer.transferData(new USB(){
            @Override
            public void start(){
                System.out.println("固态硬盘开始工作");
            }

            @Override
            public void stop() {
                System.out.println("固态硬盘工作完成");
            }
        });
    }
}
class Computer{
    //用电脑和一个有usb接口的设备做连接,但是不知道是什么设备
    //这个时候就使用多态的概念,usb接口 = 不同设备对象
    public void transferData(USB usb){
        System.out.println("设备连接成功……");
        usb.start();
        System.out.println("数据传输的细节……");
        usb.stop();
    }
}
interface USB{
    //声明一些常量,比如USB的长、宽、高、引脚数目……
    //方法
    void start();
    void stop();
}

class Printer implements USB{
    //打印机实现USB接口
    @Override
    public void start() {
        System.out.println("打印机开始工作");
    }

    @Override
    public void stop() {
        System.out.println("打印机打印完毕");
    }
}

class Camera implements USB{
    //相机实现USB接口
    @Override
    public void start() {
        System.out.println("相机连接成功,可传输文件到设备");
    }

    @Override
    public void stop() {
        System.out.println("文件传输完毕");
    }
}

接口的使用

1. 接口的理解:接口的本质是契约、标准、规范,就像我们的法律一样。制定好后大家都要遵守。
   > 接口体现的大多是一种功能的封装,比如子弹同时具有可以飞和攻击性两种属性
   > 在开发当中,继承一般都是体现在抽象类或是接口的继承上,纯粹的类与类之间的继承关系比较少
2. 定义接口的关键字:interface

3. 接口内部结构的说明:
   > 可以声明:
        属性:必须使用public static final修饰
        方法:jdk8之前:声明抽象方法,修饰为public abstract
             jdk8:声明静态方法、默认方法
             jdk9:声明私有方法

   > 不可以声明:构造器、代码块等


4. 接口与类的关系 :实现关系

5. 格式:class A extends SuperA implements B,C{}

A相较于SuperA来讲,叫做子类
A相较于B,C来讲,叫做实现类。


6. 满足此关系之后,说明:
> 类可以实现多个接口。
> 类针对于接口的多实现,一定程度上就弥补了类的单继承的局限性。
> 类必须将实现的接口中的所有的抽象方法都重写(或实现),方可实例化。否则,此实现类必须声明为抽象类。

7. 接口与接口的关系:继承关系,且可以多继承


8. 接口的多态性: 接口名 变量名 = new 实现类对象;


9. 面试题:区分抽象类和接口

> 共性:都可以声明抽象方法
       都不能实例化

> 不同:① 抽象类一定有构造器。接口没有构造器
       ② 类与类之间继承关系,类与接口之间是实现关系,接口与接口之间是多继承关系



  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java笔记是由北京大学青鸟教育推出的一款专门针对Java语言的学习工具。它以全面、系统、实践为特点,通过详细的代码示例和清晰的讲解,帮助学习者全面掌握Java编程语言。 Java笔记采用了线上与线下相结合的学习模式。学员可以通过手机、平板电脑、电脑等设备在线学习,还可以在学习过程中随时记录自己的学习笔记。同时,北大青鸟还为学员提供线下实践环境,学员可以在实验室里亲自动手实践所学知识,加深理解和应用。 Java笔记的内容非常全面,包括了Java语言的基本语法、面向对象编程、异常处理、流操作、多线程、数据库操作等众多知识点。除了理论知识,Java笔记还提供了大量的实例代码,可供学员参考和模仿。这样的学习方式既帮助学员理解Java的基本概念,又能让他们运用所学知识解决实际问题。 与此同时,Java笔记还注重学员的互动交流。在学习过程中,学员可以利用笔记功能记录学习心得和疑惑,还可以在论坛上与其他学员进行讨论和交流。这种互动形式既能促进学员之间的学习互助,也能更好地帮助学员理解和应用所学知识。 总之,Java笔记是北大青鸟推出的一款专注于Java语言学习的工具,通过系统的课程设置、丰富的实例代码和互动交流的方式,帮助学员全面掌握Java编程知识,提升编程能力。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值