Java基础专栏:基础
Java进阶专栏:进阶
static 关键字:修饰符,可以修饰成员变量和成员方法
特点:
1. 被类的所有对象所共享
2. 多了一种调用方式,可以通过类名直接调用(推荐使用类名调用)
3. 随着类的加载而加载,优先于对象存在
package com.liujintao.mystatic;
class Student {
String name;
int age;
static String school;
}
package com.liujintao.mystatic;
/*
static 关键字:修饰符,可以修饰成员变量和成员方法
特点:
1. 被类的所有对象所共享
2. 多了一种调用方式,可以通过类名直接调用(推荐使用类名调用)
3. 随着类的加载而加载,优先于对象存在
*/
public class StaticDemo1 {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "张三";
stu1.age = 23;
stu1.school = "人工智能竞赛";
System.out.println(stu1.name + "---" + stu1.age + "---" + stu1.school);
System.out.println("---------------------------");
Student stu2 = new Student();
stu2.name = "李四";
stu2.age = 24;
System.out.println(stu2.name + "---" + stu2.age + "---" + stu2.school);
}
}
张三—23—人工智能竞赛
李四—24—人工智能竞赛
就因为school被static修饰,所以,它依旧能够被共享使用
Student stu3= new Student();
System.out.println(stu3.name + "---" + stu3.age + "---" + stu3.school);
null—0—人工智能竞赛
System.out.println(Student.school);
人工智能竞赛
System.out.println(Student.school);
Student stu1 = new Student();
null
因为没有初始值,所以这里结果为默认值。
只要类被字节码加载!static静态 修饰的成员就会在 堆空间创建一个 类静态成员变量区。专门存放静态方法数据。
1. 成员方法什么时候加入 static
- 常用于制作工具类
2. 工具类: 不是描述的事物的,而是帮我们完成一些事情(打工)
3. 如果发现一个类中,所有的方法,全是 static 所修饰
- 那么我们就要手动的修饰类的 构造方法
- 目的:为了不让其他类,在创建对象
创建一个工具类:
package com.liujintao.tools;
public class ArrayTools {
// 将构造方法私有化(因为可以通过类名访问我里面的方法了,不需要再开辟空间了)
private ArrayTools(){};
/**
* 求数组最大值方法
*/
public static int getMax (int[] arr) {
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
return max;
}
/**
* 求数组最小值方法
*/
public static int getMin (int[] arr) {
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (min > arr[i]) {
min = arr[i];
}
}
return min;
}
/**
* 遍历数组方法
*/
public static void forInput (int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length - 1; i++) {
System.out.print(arr[i] + ",");
}
System.out.print(arr[arr.length - 1] + "]");
}
}
测试使用工具类方法
package com.liujintao.tools;
public class Test {
public static void main(String[] args) {
int[] arr = {11, 22, 33};
// 静态方法直接还用类名访问调用里面的方法(不需要构造器创建对象了)
System.out.println(ArrayTools.getMax(arr));
System.out.println(ArrayTools.getMin(arr));
ArrayTools.forInput(arr);
}
}
输出结果:
33
11
[11,22,33]
问:
为什么这里不需要创建实例对象呢?
答:
static修饰的成员方法,变成了静态类(可以直接访问里面的方法了),没必要在使用构造器创建对象再操作了。记得将工具类里面的构造方法私有化,避免产生浪费。
package com.liujintao.mystatic;
/*
演示静态静态类在不通过实例的时候,我们只能访问到静态的成员变量和方法
*/
public class StaticDemo2 {
static String name= "张三";
static int age = 18;
char gender = '男';
private StaticDemo2(){}; // 将构造方法私有化
/**
* 创建一个静态方法
*/
public static void Method1 () {
System.out.println("我是静态方法");
}
/**
* 创建一个非静态的成员方法
*/
public void Method2 () {
System.out.println("我是一个非静态的成员方法");
}
// 静态的主方法
public static void main(String[] args) {
// 1. 不使用构造器构造实例(直接访问)
System.out.println(name);
System.out.println(age);
Method1();
// 2. 访问非静态的成员(报错),因为类都没被加载使用
// System.out.println(gender); 报错(因为非静态的,需要构造对象使用)
// Method2(); 报错
/**
* 解决方案
*/
StaticDemo2 sd = new StaticDemo2();
System.out.println(sd.gender);
sd.Method2();
}
}
父类中非私有的成员
。继承的格式:
- 格式:
public class 子类名 extends 父类名{}
- 示范:
public class zi extends fu {}
- fu: 是父类,也被叫为 基类、超集
- zi: 是子类,派生类
创建类的细节:
package com.liujintao.mextends;
public class ExtendsDemo1 {
public static void main(String[] LiuJinTao) {
// 子类访问非私有化的父类成员
Zi1 z1 = new Zi1();
System.out.println(z1.name = "张三");
System.out.println(z1.age = 23);
System.out.println(z1.gender = '男');
// 子类访问父类私有化的成员方法 (get 和 set)
Zi2 z2 = new Zi2();
z2.setScore(99);
z2.setPrice(999.99);
System.out.println(z2.getScore() + "---" + z2.getPrice());
}
}
// 父类
class Fu {
String name;
int age;
char gender;
private double score;
private double price;
// 通过JavaBean中的get和set方法实现子类访问父类私有化的成员
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
// 子类继承父类 Fu
class Zi1 extends Fu {
}
// 子类继承父类 Fu
class Zi2 extends Fu {
}
输出示例:
张三
23
男
99.0---999.99
项目经理: 姓名 、 工号、工资
程序员: 姓名、 工号、 工资
如果字符类中出现了重名的成员变量,使用的时候依旧是根据就近原则。
package com.liujintao.mextends;
import java.sql.SQLOutput;
public class ExtendsDemo2 {
public static void main(String[] args) {
ZiClass zi = new ZiClass();
zi.method();
}
}
class FuClass {
int num = 10;
}
class ZiClass extends FuClass {
int num = 20;
public void method () {
System.out.println(num); // 就近原则 : 20
System.out.println(super.num); // 访问父类 : 10
}
}
class FuClass {
int num = 10;
}
class ZiClass extends FuClass {
int num = 20;
public void method () {
int num = 30;
System.out.println(num); // 就近原则 : 30
System.out.println(super.num); // 访问父类 : 10
System.out.println(this.num); // 调用本类成员:20
}
}
上面代码就实现了使用不同的关键字访问了不同类作用域中的成员变量。
字父类中,出现了方法声明一模一样的方法(方法名、参数、返回值)
- 在创建子列对象,调用方法的时候,会优先使用子类的方法逻辑
- 很像就近原则,但其实是子类的方法,对父类的方法, 进行了重写操作
public Text {
Zi z = new Zi();
z.show() // 我是子类方法
}
// 父类
class Fu {
public void show() {
System.out.println("我是父类方法");
}
}
// 子类
class Zi {
public void show () {
System.out.println("我是子类方法");
}
}
方法重载(Overload):在同一个类中,方法名相同,参数不同,与返回值无关 → 参数不同:类型不同,个数不同,顺序不同
方法重写(Override):在子父类中,出现了方法声明一模一样的方法(方法名,参数,返回值)相同的。
package com.liujintao.mextends;
public class ExtendesDemo3 {
public static void main(String[] LiuJinTao) {
Son s = new Son();
s.classHandle();
}
}
class Fathod {
public void classHandle() {
System.out.println("起床");
System.out.println("吃饭");
System.out.println("睡觉");
}
}
class Son extends Fathod {
@Override
public void classHandle() {
// 使用super关键字指定父类的方法,如果我们重写这个方法不需要(可以删除)
super.classHandle();
// 下面我们就可以重写方法(这里添加逻辑)
System.out.println("我是方法重写");
System.out.println("但是我保留了父类方法中的逻辑");
}
}
输出示例:
起床
吃饭
睡觉
我是方法重写
但是我保留了父类方法中的逻辑
要么继承一个,要么多层继承,不能同时继承多个。
实现多层继承的代码实现:
package com.liujintao.mextends;
public class ExtendxDemo04 {
public static void main(String[] LiuJinTao) {
C c = new C();
c.methodC(); // 调用本类方法
c.methodB(); // 调用继承的父级类方法
c.methodA(); // 调用父级继承的爷爷类方法
}
}
class A {
public void methodA () {
System.out.println("我是爷爷辈");
}
}
class B extends A {
public void methodB () {
System.out.println("我是父亲辈");
}
}
class C extends B {
public void methodC () {
System.out.println("我是儿子辈");
}
}
输出示例:
我是儿子辈
我是父亲辈
我是爷爷辈
问题1: 构造方法能否被继承?
回答2:不能继承构造方法,因为构造方法只能和类重名。
问题2:子类在创建前是否要先初始化父类?
回答2: 是的,因为子类创建的时候,可能需要涉及到父类。
问题3:子类是如何完成父类的初始化的呢?
回答3:子类只需要能访问到父类的构造方法就能实现
问题4:什么方法是用于对象初始化的?
回答4:构造方法
直接下结论:
super();
细节:
package com.liujintao.mextends.construction;
public class constructionDemo {
public static void main (String[] LiuJinTao) {
Zi zi = new Zi();
Zi z2 = new Zi(520);
}
}
class Fu {
public Fu () {
super(); // 指向的是上级,没有继承则为:Object
System.out.println("我是父类空参构造器");
}
public Fu (int num) {
System.out.println("我是父类带参构造器");
}
}
class Zi extends Fu{
public Zi () {
super();
System.out.println("我是子类空参构造器");
}
public Zi (int num) {
super();
System.out.println("我是子类带参构造器");
}
}
输出示例:
我是父类空参构造器
我是子类空参构造器
我是父类空参构造器
我是子类带参构造器
创建一个父类
package com.liujintao.test;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
}
创建第一个子类:
package com.liujintao.test;
public class Teachar extends Person {
// 两个构造器
public Teachar () {}
public Teachar (String name, int age) {
super(name, age);
}
public void teach () {
System.out.println("姓名为" + super.getName() + ",年龄为" + super.getAge() + "岁的老师正在讲课");
}
}
创建第二个子类:
package com.liujintao.test;
public class Student extends Person {
private double score;
public Student () {
}
public Student (String name, int age, double score) {
super(name, age);
this.score = score;
}
public void study () {
System.out.println("姓名为" + super.getName() + ",年龄为" + super.getAge() + "岁,成绩为" + score + "分的学生,正在学习");
}
}
测试类操作两个子类:
package com.liujintao.test;
public class Test {
public static void main(String[] LiuJinTao) {
Teachar th = new Teachar("张三", 24);
Student stu = new Student("李四", 18, 99.9);
th.teach();
stu.study();
}
}
输出示例:
姓名为张三,年龄为24岁的老师正在讲课
姓名为李四,年龄为18岁,成绩为99.9分的学生,正在学习
需求:
代码如下:
测试类代码:
package com.liujintao.test2;
/**
* 我是测试类
*/
public class Test {
public static void main(String[] LiuJinTao) {
Coder code = new Coder("张三", 23, 15000);
Manager mg = new Manager("李四", 24, 18000, 5000);
// 调用两个子类的的方法
code.work();
mg.work();
}
}
父类代码:
package com.liujintao.test2;
import com.liujintao.mextends.A;
/**
* 我是一个员工类
*/
public class Emeployee {
private String name;
private int age;
private int wage;
public Emeployee() {
}
public Emeployee(String name, int age, int wage) {
this.name = name;
this.age = age;
this.wage = wage;
}
/**
* 方法类
*/
public void work () {
System.out.println("姓名为" + name + ",年龄为" + age + ",工资为" + wage + "的程序员正在编写代码");
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
A
/**
* 获取
* @return wage
*/
public int getWage() {
return wage;
}
/**
* 设置
* @param wage
*/
public void setWage(int wage) {
this.wage = wage;
}
}
子类1代码:
package com.liujintao.test2;
/**
* 我是程序员类
*/
public class Coder extends Emeployee {
// 通过构造器获取数据
public Coder (String name, int age, int wage) {
// 通过 super 操作父级的构造器,初始化父级类中的成员变量
super(name, age, wage);
};
}
子类2代码:
package com.liujintao.test2;
/**
* 我是项目经理类
*/
public class Manager extends Emeployee {
// 奖金
private int bonus;
// 该构造方法接受到实例传递过来的数据,然后通过构造器里面的super方法操作父级的构造器,从而实现初始化数据
public Manager (String name, int age, int wage, int bonus) {
super(name, age, wage);
// 多出来的变量我们自己处理就好了
this.bonus = bonus;
}
public void work () {
// 使用方法重写(并且不继承父级该方法的原有属性)
System.out.println("姓名为" + super.getName() + ",年龄为" + super.getAge() + ",工资为" + super.getWage() + "奖金为" + bonus + "的项目经理正在分配任务...");
}
}
输出示例:
姓名为张三,年龄为23,工资为15000的程序员正在编写代码
姓名为李四,年龄为24,工资为18000奖金为5000的项目经理正在分配任务...
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
---|---|---|---|
this | this.本类成员变量 | this.本类成员方法(); | this(); this(…);本类构造方法 |
super | super.父类成员变量 | super.父类成员方法 | super(); super(…);父类构造方法 |
注意:this() 和 super() 都在争夺构造方法第一行的位置,所以二者不能共存。
final:关键字(最终)的意思,可以用来修饰(方法、类、变量)
final: 修饰的特点:
final 命名规范:
一个单词全部大写:max → MAX
多个单词全部大写,单词之间使用_隔开:maxValue → MAX_VALUE
final修饰变量的细节补充:
本期需要掌握的知识点。
Java进阶开始了(更新中…)加油