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


数据
数据 数据行为 数据集合 : 变量+常量 方法/函数 类+接口
类(类本身也算是一种对象吧)/实例对象: 抽象与实现 继承: 是一种衍生
数据=变量+常量
8 种基本数据类型:byte,short,int,long,float,double,char 和 boolean
变量是指一个包含值的存储地址以及对应的符号名称!!! 变量的名字和变量的值
变量就是存储数据的载体
- 类变量使用
static关键字修饰,是静态变量static修饰符告诉编译器,无论类被实例化多少次,类变量始终只有一个变量副本。只要类被加载到内存中,它就会存在 - 实例变量也被称为非静态字段 实例变量用于存储对象的状态,它的值对于类的每个实例都是唯一的,每个对象都拥有自己的变量副本。只要相应的对象存在于内存中,它就占用着存储空间
- 局部变量是在方法范围内被声明和使用的,局部变量只对声明它们的方法可见,方法返回后,它们将被销毁。它们没有任何关键字修饰(它们的作用范围限制在一个方法、构造函数或块内部,不需要额外的修饰符来说明访问权:局部变量的作用范围在定义它的代码块内,一旦超出了该代码块,局部变量将不再可见.
- 参数是用于传递给方法签名的变量
常量 需用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成员是每个实例独有的。- 可以将
static和final结合使用来创建类级别的常量,例如: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 个必要条件:
- 满足继承关系
- 要有重写
- 父类引用指向子类对象
向上转型实际上是把一个子类型安全地变成了更加抽象的父类型,向上转型又称为自动转型、隐式转型。向上转型就是父类引用指向子类实例,也就是子类的对象可以赋值给父类对象
向上转型是父类引用指向子类实例,向下转型是让子类引用指向父类实例。向下转型也被称为强制类型转换
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
浙公网安备 33010602011771号