java1

笔记的主要参考来源  http://www.imooc.com/wiki/javalesson

数据

数据  数据行为  数据集合  :  变量+常量  方法/函数  类+接口

类(类本身也算是一种对象吧)/实例对象:  抽象与实现    继承:  是一种衍生

数据=变量+常量

 8 种基本数据类型:byteshortintlongfloatdoublechar 和 boolean

变量是指一个包含值的存储地址以及对应的符号名称!!!  变量的名字和变量的值

变量就是存储数据的载体

  1. 类变量使用static关键字修饰,是静态变量  static修饰符告诉编译器,无论类被实例化多少次,类变量始终只有一个变量副本。只要类被加载到内存中,它就会存在
  2. 实例变量也被称为非静态字段  实例变量用于存储对象的状态,它的值对于类的每个实例都是唯一的,每个对象都拥有自己的变量副本。只要相应的对象存在于内存中,它就占用着存储空间
  3. 局部变量是在方法范围内被声明和使用的,局部变量只对声明它们的方法可见,方法返回后,它们将被销毁。它们没有任何关键字修饰(它们的作用范围限制在一个方法、构造函数或块内部,不需要额外的修饰符来说明访问权:局部变量的作用范围在定义它的代码块内,一旦超出了该代码块,局部变量将不再可见.
  4. 参数是用于传递给方法签名的变量

常量  需用final修饰  一般在声明时赋值,被赋值后,在程序的运行过程中不允许被改变

数组声明和初始化

        int[] age;
        age =new int[]{22,23,24};
        int[] number1=new int[]{1,2};
        int[] number2={1,2,3};

        int[] number3=new int[100]    //表示数组由100个元素组成

修饰符

public、protected、private、default、  final、static、abstract

访问(权限)修饰符:类,类成员(数据,方法)

protected  子类可以访问父类的 protected 成员,即使子类和父类不在同一个包中 

非访问修饰符:

final、static、abstract  这些修饰符用于控制类、方法、数据的行为

  • static  表示静态:指定(内部类和?)类成员(数据,方法)属于类而不是实例,这是关于类/对象的一个重点知识(类本身也算是一种对象),它们在内存中只有一份拷贝,被所有类的实例共享。还可以用于修饰内部类
    • 用static修饰的内部类,称为静态内部类,完全属于外部类本身,不属于外部类某一个对象。注意:外部类不可以定义为静态类,Java中静态类只有一种,那就是静态内部类.
      • 静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外部类,但是静态内部类却没有。没有这个引用就意味着:

        1、可以在没有外部类实例的情况下被实例化,可以通过 OuterClass.StaticInnerClass 直接访问静态内部类,而不需要先创建外部类的实例..静态内部类是主类的一部分,而且只能通过主类来创建它的实例。这意味着,静态内部类不能被从外部访问       2、它不能使用任何外部类的非static成员变量和方法

      • Java的静态内部类主要是为了实现以下需求

          1将相关类组织在一起 有时候,为了以组织方式汇总实现,多个类需要紧密地关联。使用静态内部类将这些类直接嵌套在主类中,可以更清晰、更简洁地编写代码。

  • final  表示不变:用于表示类和类成员(数据,方法)是不可修改的。类被修饰为 final 时,不能被继承。方法被修饰为 final 时,不能被子类重写。通过使用 final 关键字,可以确保某个类不被继承,或者某个方法不被重写,从而增强代码的安全性和稳定性..变量被修饰为 final 时,成为常量final修饰的成员变量(即常量)必须在声明时或构造函数中初始化,一旦初始化后就不能再修改。
  • static和final  
    • static 用于创建类级别的成员,而 final 用于创建不可修改的变量(即常量)或确保方法或类的不变性
    • static 成员可以被类的所有实例共享,而 final 成员是每个实例独有的。
    • 可以将 staticfinal 结合使用来创建类级别的常量,例如:public static final int MAX_VALUE = 100;,这样的变量通常用大写字母命名,表示常量。
    • static 可以用于修饰内部类,但 final 不能。
  • static final 声明一个静态常量,被赋值后,在程序的运行过程中不允许被改变,可以在类的任何实例中使用
  • abstract:用于声明抽象类或抽象方法。抽象类不能被实例化,抽象方法只有声明,没有实现。

 

类  

由这些元素构成:  构造方法  成员属性(即数据)  成员方法  静态变量(或常量)即类属性  静态方法即类方法  内部类

  • 对象的实例化,我们是使用 new 关键字 + 构造方法名 () 来实现的。
  • 当类内部我们没有显示定义构造方法时,系统会自动添加无参的构造方法;当在类内部显示定义了构造方法,系统不会自动添加无参构造方法。
  • this 关键字可以解决实例变量和参数变量冲突的问题;this 关键字也可以调用同一类中其他的成员方法。

在类中,事物的静态特征被抽象成属性,事物的动态行为被抽象成方法

  • 静态变量:也称为类属性,它是同一个类的任何对象所共有的。
  • 静态方法:也称为类方法,静态方法是不影响特定对象的方法;内部类:可以将一个类包含在另一个类中,常用于该类仅提供给声明它的类使用的情况;
  • 构造方法:生成新对象的特殊方法;
  • 参数化类型:可以在定义期间将参数化类型分配给类。 参数化类型将替换为在类实例化时指定的类型。 它由编译器完成。 它类似于 C 语言宏#define 语句,其中预处理器评估宏。

构造方法  

public  构造方法名(参数){  }构造方法没有返回类型  方法名要与类名同名

如果我们没有定义构造方法的情况下,系统会有一个默认的构造方法。换句话说:任何一个类都会有一个构造方法。构造方法只能在对象的实例化时使用,也就是说,构造方法只能配合 new 关键字使用

this指向当前实例对象的引用  使用 new 关键字调用构造方法

public class ImoocStudent {
    // 定义属性(特征)
    String nickname;  // 昵称
    // 定义方法(行为)
    public ImoocStudent(String nickname) {
        //如果参数列表中参数变量的命名和实例属性相同。将无法完成对实例属性的赋值,也就是说,下面的写法是错误的:
        //nickname = nickname;
        //正确的写法
        //在方法内部,this 关键字是当前对象的默认引用,简单说,谁调用了它谁就是 this。
        // 因此,通过 this.field 就可以访问当前实例的字段,解决实例变量和参数变量名称冲突的问题
        this.nickname = nickname;
    }
    public static void main(String[] args) {
        //使用 new 关键字调用构造方法
        ImoocStudent zwj = new ImoocStudent("xiwa");
        System.out.println("zwj的外号叫:"+zwj.nickname);
    }
}

方法

方法重写规则:

参数列表要一样  返回类型和访问控制符不一定要和原方法完全相同,但要合理  构造方法不能重写

  • 重载: 方法重载允许在同一个类中定义多个方法(构造方法也可以重载),方法名相同但参数列表不同。编译器根据方法调用时的参数类型和数量决定调用哪个重载方法。
  • 方法的参数分基本类型和引用类型,有不同的情况
public class Run {
    public void yiqipao(int speed,String[] name) {
        System.out.println("初始速度:"+speed);
        speed++;
        System.out.println("加速后的速度:"+speed);
        name[1]="zou";
    }

    public static void main(String[] args) {
        int speed=60;
        String[] name=new String[]{"zwj","shijian","xiwa"};
        System.out.println("调用方法前的数据情况"+speed+name[1]);
        Run run=new Run();
        run.yiqipao(speed,name);
        //调用方法后,基本类型(speed)的数据不变,引用类型(name)的数据变了
        System.out.println("调用方法后的数据情况:"+speed+name[1]);
    }
}
//注释
public class MathUtils {
    /**
     * Calculates the sum of two integers.
     *
     * @param a 用于求和的数据之一.
     * @param b 用于求和的数据之一.
     * @return 两数之和
     */
    public int sum(int a, int b) {
        return a + b;
    }

    /**
     * Divide two numbers.
     *
     * @param dividend 除数
     * @param divisor  被除数
     * @return 两数相除的结果
     * @throws ArithmeticException 当被除数是0时,抛出算术异常
     */
    public double divide(double dividend, double divisor) throws ArithmeticException {
        if (divisor == 0) {
            throw new ArithmeticException("Divisor cannot be zero.");
        }
        return dividend / divisor;
    }
    
}

封装  

封装是将对象的状态和行为包装在一起,并限制对其直接访问。通过访问修饰符(如 private、protected、public)控制属性和方法的可见性,从而实现数据的隐藏和安全性。

//封装
public class BankAccount {
    /**
     * balance  余额
     * amount   金额
     * deposit  存款
     * withdraw 取款
     */
    private String accountNumber;
    private double balance;

    public BankAccount(String accountNumber, double initialBalance) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }

    //以下是两个getter
    public String getAccountNumber() {
        return accountNumber;
    }

    public double getBalance() {
        return balance;
    }

    //存款
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("余额增加:" + amount);
        }
    }

    //取款
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("取走:" + amount);
        } else {
            System.out.println("大哥,你没存那么多钱啊!想我们银行倒贴钱给你啊");
        }
    }

    public static void main(String[] args) {
        BankAccount ba = new BankAccount("0577", 0);
        System.out.println("目前余额为:" + ba.getBalance());
        ba.withdraw(1000);

        ba.deposit(10000);
        System.out.println("目前余额为:" + ba.getBalance());

        ba.withdraw(100);
        System.out.println("目前余额为:" + ba.getBalance());

        System.out.println("账户Id:" + ba.getAccountNumber());
    }
}
NbaPlayer.java
//封装    我们认为nickname是可以被随意修改的,其他属性是不可以被随意修改的,(id不在讨论范围内)
public class NbaPlayer {
    private String name;
    public String nickname;
    private int age;
    public int id;

    public NbaPlayer(String name, int age, String nickname) {
        setAge(age);
        this.name = name;
        this.nickname = nickname;
    }


    //以下共4个setter/getter   age,name,id,缺少了setName和setId
    public void setAge(int age) {
        //球员最小注册年龄16,小于16抛出-1
        if (age < 16) {
            age = -1;
        }
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
}

SomeNbaPlayer.java
public class SomeNbaPlayer {
    public static void main(String[] args) {
        NbaPlayer[] n = new NbaPlayer[100];

        n[0] = new NbaPlayer("zwj", 28, "xiwa");
        n[1] = new NbaPlayer("zwj", 29, "xiwa");
        n[2] = new NbaPlayer("zwj", 30, "xiwa");
        n[3] = new NbaPlayer("zwj", 28, "xiwa");
        //在以上声明(应该是声明了哈,但是只初始化(实例化)了一部分)了100个NbaPlayer类型的数据,
        // 以下是对实例化了的对象的属性进行赋值
        for (int i = 0; i < 100; i++) {
            if (n[i] != null){
                n[i].id = i + 1;
            }
        }
        System.out.println(
                "n[0]  姓名:" + n[0].getName() +
                        "   绰号:" + n[0].nickname +
                        "   年龄:" + n[0].getAge() +
                        "   id:" + n[0].id
        );
        //从以上输出结果可知nickname不好听,所以重新给nickname赋值
        n[0].nickname = "杰哥";
        System.out.println(
                "n[0]  姓名:" + n[0].getName() +
                        "   绰号:" + n[0].nickname +
                        "   年龄:" + n[0].getAge() +
                        "   id:" + n[0].id
        );
        //以下不能直接写n[2].name和n[2].age,因为这两个属性都是私有属性
        System.out.println(
                "n[2]  姓名:" + n[2].getName() +
                        "   绰号:" + n[2].nickname +
                        "   年龄:" + n[2].getAge() +
                        "   id:" + n[2].id
        );
        //以上输出的age为-1,所以需要setAge
        n[2].setAge(29);
        System.out.println("n[2]   姓名:" + n[2].getName() +
                "   绰号:" + n[2].nickname +
                "   年龄:" + n[2].getAge() +
                "   id:" + n[2].id);

        System.out.println(""+n[3].id);
    }
}

继承  

继承允许一个类从另一个类继承属性和方法,促进了代码重用和层次化设计。子类可以扩展父类的功能,并可以重写继承的方法

继承可以使得子类具有父类别的各种属性和方法,而不需要再次编写相同的代码  继承父类所有开放的特征

super 是用在子类中的,目的是访问直接父类的变量或方法

  • 调用父类构造方法
  • 引用父类的属性
  • 调用父类方法
//Employee.java
import java.time.LocalDate;
public class Employee {
    private double salary;//薪水
    private String name;
    private LocalDate hireDay;//工龄
    public Employee(double salary, String name, int year, int month, int day) {
        this.salary = salary;
        this.name = name;
        this.hireDay = LocalDate.of(year, month, day);
    }
    public double getSalary() {
        return salary;
    }
    public String getName() {
        return name;
    }
    public LocalDate getHireDay() {
        return hireDay;
    }
    /**
     *
     * @param byPercent byPercent/100:涨幅
     */
    public void raiseSalary(double byPercent){
        double raise=salary*byPercent/100;
        salary += raise;
    }
}

//Employee.java
public class Manager extends Employee {
    private double bonus;//奖金
    /**
     * @param salary 薪水
     * @param name
     * @param year   工龄年月日
     * @param month
     * @param day
     */
    public Manager(double salary, String name, int year, int month, int day) {
        super(salary, name, year, month, day);
        bonus = 0;
    }
    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    @Override
    public double getSalary() {
        double baseSalary = super.getSalary();
        return baseSalary + bonus;
    }
}

//Main
public class Main {
    public static void main(String[] args) {
        Manager boss=new Manager(8000,"cc",2010,1,15);
        boss.setBonus(7500);
        Employee[] staff=new Employee[3];
        staff[0]=boss;
        staff[1]=new Employee(5000,"zz",2015,1,1);
        staff[2]=new Employee(5500,"sj",2015,2,1);
        for (Employee employee : staff) {
            System.out.println("name:"+employee.getName()+"    薪水:"+employee.getSalary()+
                    "  工龄:"+employee.getHireDay());
        }
    }
}

 

多态  

多态意指相同的消息给予不同的对象会引发不同的动作,多态意味着允许不同类的对象对同一消息做出不同的响应

在 Java 中实现多态有 3 个必要条件:

  1. 满足继承关系
  2. 要有重写
  3. 父类引用指向子类对象

向上转型实际上是把一个子类型安全地变成了更加抽象的父类型,向上转型又称为自动转型、隐式转型。向上转型就是父类引用指向子类实例,也就是子类的对象可以赋值给父类对象

向上转型是父类引用指向子类实例,向下转型是子类引用指向父类实例。向下转型也被称为强制类型转换

class Pet {
    // 定义方法 eat
    public void eat() {
        System.out.println("宠物吃东西");
    }
}
// 为Cat类增加run方法
class Cat extends Pet { // 继承父类
    // 重写父类方法 eat
    public void eat() {
        System.out.println("猫猫吃猫粮");
    }
    public void run() {
        System.out.println("猫猫跑步");
    }
    public static void main(String[] args) {
        // 设置变量类型为父类类型即向上转型
        Pet pet = new Cat();//宠物类,猫类
        boolean b = pet instanceof Cat;
        System.out.println("pet是Cat类的实例吗:" + b);
        // 向下转型:强制类型转换   这里将Pet类型的pet转换成Cat类型,只有转换为Cat对象后,才能调用Cat类的run方法
        //做一下判断:pet是否是Cat类的实例,是的话才能转换成Cat类型
        if (pet instanceof Cat) {
            //将Pet类型的pet强制转换成Cat类型
            //这里是引用传递,catObj和pet(强制转换后是Cat类型)都是对一个Cat类型的实例的引用
            Cat catObj = (Cat) pet;
            System.out.println("调用Cat类的run方法输出:");
            catObj.run();
        }
    }
}

抽象  

抽象类不能被实例化的类,它可以包含抽象方法和具体方法。子类必须实现父类中的抽象方法

在面向对象编程中,所有的对象(实例)都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象(实例)的,

如果一个类中没有包含足够的信息来构造一个实例,那么这样的类就是抽象类

抽象方法  抽象类中可以包含抽象方法,它是没有具体实现的方法。换句话说,与普通方法不同的是,抽象方法没有用 {} 包含的方法体

abstract class Pet{
    abstract void eat();
    private String name;
    public String getName() {
        System.out.println("name:"+name);
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

class Cat extends Pet { // 继承父类
    // 实现eat方法
    public void eat() {
        System.out.println("猫猫吃猫粮");
    }
    public static void main(String[] args) {
        Cat cat =new Cat();
        cat.setName("little");
        cat.eat();
        cat.getName();
    }
}

从设计层面来说,抽象是对类的抽象,是一种模板设计,而接口是对行为的抽象,是一种行为的规范

接口

接口是为了解决java单继承的弊端而产生的

多个接口存在同名的default方法,这会产生冲突,解决办法是在实现类中重写这个默认方法

父类中存在与接口中默认(default)方法同名的方法,这种情况没有问题,不会报错,在没有重写的情况下,会执行父类的方法

 多个接口中存在重名常量,不会出错,但父类中存在与接口中常量同名的数据时,会报错,此时应该在实现类中声明一个同名的数据

interface shengwu{
    void huxi();
}
/**
 * 接口本质上还是类,也存在继承关系
 *接口声明:对接口的访问控制可以是public,protected,default,不可以是private
 * 接口中可以定义常量,常量默认是public final static的
 * 方法默认都是public abstract(抽象),也可以显示声明修饰符为default或static的方法
 *
 */
interface Person extends shengwu{
    String name="我是Person中的常量";
    void run();
    void walk();
    default void eat(){
        System.out.println("默认的吃方法");
    }
    static void sayHello(){
        System.out.println("hello shijian!");
    }
}

public class Student implements Person{
    @Override
    public void run() {
        System.out.println(Person.name);
        System.out.println("学生都很年轻,跑步都比较快");
    }
    @Override
    public void huxi() {
        System.out.println("学生的呼吸也就是心肺能力都比较好");
    }
    @Override
    public void walk() {
        Person.sayHello();
        System.out.println("学生都很年轻,走路都比较快,懒散的除外");
    }
    /**
     * 重写接口中的默认方法,以下用public是合理的,参考方法重写的规则
     */
    @Override
    public void eat() {
        //接口.super是接口的引用,和父类的引用有区别把,单继承只有一个父类
        //但是可以实现多个接口,所以要写清楚是对哪个接口的引用
        Person.super.eat();
        System.out.println("学生狼吞虎咽的吃东西");
    }
}

内部类

你好

章节一

章节一

章节一

 

https://www.cnblogs.com/east7/p/16905767.html

 

posted @ 2023-08-20 05:04  zouyijian  阅读(46)  评论(0)    收藏  举报