Day13
一、static
1.1 定义
- java中的关键字,表示静态的
- 可以修饰变量、方法、类、代码块
二、static修饰变量
2.1 定义
-
被static修饰的变量成为静态变量
-
存储的位置发生改变
- 普通的变量在对象创建完成后存储在堆内存
- 静态的变量随着类的加载而加载到方法区
- 静态变量被所有此类的实例对象共享
- 可以使用对象名调用,也可以使用类名调用
2.2 案例
package com.qf.static1;
public class Demo01 {
public static void main(String[] args) {
Stu stu = new Stu();
System.out.println(stu.name);
System.out.println(stu.captial);
stu.name = "张三丰";
stu.captial = "首尔";
System.out.println(stu.name);
System.out.println(stu.captial);
Stu stu2 = new Stu();
System.out.println(stu2.name);
System.out.println(stu2.captial);
}
}
class Stu{
String name = "张三";
static String captial = "汉城";
}
2.3 static修饰局部变量
- 局部变量不能使用public、static、private等修饰符修饰
三、静态方法
3.1 定义
- 使用static修饰的方法成为静态方法
- 静态方法可以直接使用类名调用
- 类名.静态方法()
- 也可以通过创建对象来调用,推荐使用类名调用
3.2 静态方法调用变量
- 静态方法只能调用静态变量
- 普通方法可以调用普通成员变量和静态变量
package com.qf.static1;
public class Demo02 {
public static void main(String[] args) {
Programmer p = new Programmer();
p.show();
Programmer.getInfo();
}
}
class Programmer{
String name;
int age;
static String captial = "汉城";
public void show() {
System.out.println("我的名字是" + name + "我今年" + age);
System.out.println(captial);
}
/**
* 静态方法只能引用静态变量
*/
public static void getInfo() {
System.out.println("我来自" + captial);
}
}
3.3 继承关系中的静态方法和变量
- 静态变量
- 可以被子类继承
- 不能被子类重写
- 如果子类中也有重名的变量,那是子类自己的,和父类无关
- 静态方法
- 可以被子类继承
- 不能被子类重写
- 如果子类中有重名的方法,是子类自己的,和父类无关
package com.qf.static1;
public class Demo03 {
public static void main(String[] args) {
// fun01();
Animal animal = new Dog();
animal.show("haha");
System.out.println(animal.type);
}
private static void fun01() {
Pig pig = new Pig();
System.out.println(pig.type);
System.out.println(Pig.type);
Pig.show("荷兰猪");
// 子类修改继承到的静态变量,父类会不会受到影响
Pig.type = "猪";
System.out.println(Animal.type);
}
}
/**
* 动物类,当做父类使用
* @author Dushine2008
*
*/
class Animal{
static String type = "动物";
String name;
int age;
public void eat() {
System.out.println("动物需要进食");
}
public static void show(String type) {
System.out.println("我是" + type);
}
}
class Pig extends Animal {
}
class Dog extends Animal{
static String type = "道哥";
String name;
int age;
@Override
public void eat() {
System.out.println("狗子喜欢吃骨头");
}
// @Override
public static void show(String type) {
System.out.println("我叫" + type);
}
}
四、代码块
4.1 定义
- 代码块就是一块代码,写在{}里面
- 根据位置和功能分为四种
- 局部代码块
- 构造代码块–动态代码块
- 静态代码块
- 同步代码块
4.2 局部代码块
- 定义在方法里面
- 生命周期贼短
- 适用一些生命周期也很短的变量、代码等操作
package com.qf.block;
public class Demo01 {
public static void main(String[] args) {
System.out.println("Hello Java!1");
System.out.println("Hello Java!2");
System.out.println("Hello Java!3");
int i = 10;
{
// 适用一些生命周期特别短的变量、代码
String secret = "我有一个小秘密";
System.out.println("我是局部代码块");
System.out.println(secret);
System.out.println(i);
}
// System.out.println(secret);
System.out.println("Hello Java!4");
System.out.println("Hello Java!5");
System.out.println("Hello Java!6");
}
}
4.3 构造代码块
- 构造代码块书写在和成员变量、构造方法同级别的位置
- 执行时间早于构造方法
- 每创建一个对象,构造代码块就会执行一次
- 可以完成一些构造方法中共性的内容
- 内容加载时间
- 静态数据》》成员数据》》构造器
- 成员变量和构造代码块加载的顺序和书写的位置有关
package com.qf.block;
public class Demo02 {
public static void main(String[] args) {
Human human1 = new Human();
Human human2 = new Human("");
Human human3 = new Human("",10,"");
}
}
class Human{
int age;
String info;
static int count = 0;
String name = "张三";
public Human(){
count++;
System.out.println("我是空参构造方法");
}
public Human(String name) {
count++;
this.name = name;
System.out.println("我是一个参数构造方法");
}
public Human(String name,int age,String info) {
count++;
this.name = name;
this.age = age;
this.info = info;
System.out.println("我是三个参数构造方法");
}
{
count++;
System.out.println("我是构造代码块");
System.out.println(name);
}
}
package com.qf.block;
public class Demo03 {
public static void main(String[] args) {
Lunch lunch = new Lunch("四个蛋炒蛋", "二斤红烧肉");
}
}
class Lunch{
String egg;
String meat;
String rice;
String bread;
{
System.out.println("客官里面请,桌子、茶水已备好");
}
public Lunch(String egg) {
this.egg = egg;
}
public Lunch(String egg,String meat) {
this.egg = egg;
this.meat = meat;
}
}
4.4 静态代码块
- 使用static修饰的代码块成为静态代码块
- 在类的使用过程中,不管创建了多少次对象,执行一次
- 静态代码块的优先级很高,在所有的成员数据、构造器之前
- 适合在加载驱动的时候使用
package com.qf.block;
public class Demo04 {
public static void main(String[] args) {
Student stu1 = new Student();
Student stu2 = new Student();
}
}
class Student{
String name;
int age;
static String schoolName = "嵩山计算机学院";
static {
System.out.println("我是静态代码块===========");
// System.out.println(schoolName);
// System.out.println(name);
// show();
}
{
System.out.println("构造代码块");
}
public Student() {
super();
System.out.println("我是构造方法");
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public static void show() {
System.out.println("hahaha");
System.out.println(schoolName);
}
}
五、final
5.1 修饰变量
- 被修饰的变量成为常量,位置到了常量池
- 只能被赋值一次
- 没有默认值,使用之前必须赋值
常量
- 字面值常量
- 1,2.3,a,c,n,m
- 自定义常量
- 使用final修饰的变量
案例
package com.qf.final1;
public class Demo01 {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1.schoolName);
System.out.println(s1.birthday);
s1.name = "王强";
s1.age = 13;
s1.schoolName = "茶阿三中";
// 使用final修饰的内容不可更改,只能赋值一次,final修饰的变量没有初始化值,比需要先赋值再使用
// s1.birthday = "1990年11月";
}
}
class Student{
String name;
int age;
static String schoolName = "茶阿二中";
final String birthday = "1990年12月";
}
5.2 修饰方法
- final可以修饰方法,被修饰的方法成为最终的方法
- 可以被子类继承、使用,不能重写
package com.qf.final1;
public class Demo03 {
public static void main(String[] args) {
MathUtil mathUtil = new MathUtil();
int sum = mathUtil.getSum(3, 5);
System.out.println(sum);
}
}
class Calculator{
public final int getSum(int a,int b) {
return a + b;
}
}
class MathUtil extends Calculator{
//被final修饰的方法不能被重写
public final int getSum0(int a,int b) {
return a + b + 10;
}
}
5.3 final修饰类
- final修饰的类不能被继承,没有子类
- 太监类
5.4 final修饰基本类型和引用类型变量的区别
- 修饰基本类型的变量,成为常量,值不可以修改
- 修饰引用类型的变量,地址值不可修改,但是对象中的元素一般是可以修改的
package com.qf.final1;
public class Demo02 {
final static int num = 10;
final static int[] arr = {11,22,33,44,55};
public static void main(String[] args) {
changeNum();
System.out.println(arr[0]);
System.out.println(arr);
changeArr();
System.out.println(arr[0]);
System.out.println(arr);
}
/**
* 编写方法修改引用类型的元素
*/
private static void changeArr() {
arr[0] = 110;
// arr = new int[10];
}
/**
* 编写方法修改基本类型的元素
*/
private static void changeNum() {
// num = num + 10;
}
}
六、抽象
6.1 定义
- 没有具体实现的
- 方法没有方法体,类不能直接创建对象
- 使用abstract修饰
6.2 抽象方法
-
使用abstract修饰的方法成为抽象方法
-
抽象方法必须放在抽象类中
-
抽象方法之后声明的部分,没有方法体
6.3 抽象类
-
使用abstract修饰的类
-
抽象类中可以存放抽象方法
-
抽象类中可以书写和普通类完全一样的内容
- 可以写成员变量
- 成员方法
- 静态变量
- 静态方法
- 静态常量
- 静态最终方法
- 空参构造方法、有参构造方法
- 抽象方法
- … …
-
抽象类无法直接创建对象,但是可以被继承
-
子类可以获取抽象类中所有的内容,根据自己的需求改写
抽象案例
package com.qf.abs;
public class Demo02 {
public static void main(String[] args) {
Computer c = new Computer();
Person p1 = new Programmer();
c.work(p1);
c.playGame(p1);
Person p2 = new Student();
c.work(p2);
c.playGame(p2);
}
}
/**
* 电脑类
* 有玩游戏和工作的方法
* 传入不同的人,工作和玩游戏的输出内容不同
* @author Dushine2008
*
*/
class Computer{
public void playGame(Person p) {
p.playGame();
}
public void work(Person p) {
p.work();
}
}
/**
* Person类
* 抽象类,有抽象的工作和玩游戏的方法
* @author Dushine2008
*
*/
abstract class Person{
public abstract void work();
public abstract void playGame();
}
/**
* Person的子类
* 重写Person中的抽象方法
* 程序员工作的方式和玩游戏的内容都有自己的特点
* @author Dushine2008
*
*/
class Programmer extends Person{
@Override
public void work() {
System.out.println("程序员的工作是编程");
}
@Override
public void playGame() {
System.out.println("我们不仅会玩游戏,有的程序员还会写游戏");
}
}
/**
* Person的子类
* 重写Person中的抽象方法
* 学生工作的方式和玩游戏的内容都有自己的特点
* @author Dushine2008
*
*/
class Student extends Person{
@Override
public void work() {
System.out.println("学生的工作是学习和适应社会");
}
@Override
public void playGame() {
System.out.println("有些人玩游戏没日没夜");
}
}
七、对象数组
- 引用类型数据的数组
- 以前用过String类型的数组
- 现在我们自定义的类也是引用类型的数据
package com.qf.abs;
public class Demo03 {
public static void main(String[] args) {
Man[] mans = new Man[5];
mans[0] = new Man("鲁智深", 22);
mans[1] = new Man("张顺", 23);
mans[2] = new Man("高俅", 44);
mans[3] = new Man("高衙内", 26);
mans[4] = new Man("林冲", 29);
for (int i = 0; i < mans.length; i++) {
if (mans[i].age > 23) {
System.out.println(mans[i].name + "=====" + mans[i].age);
}
}
System.out.println("=================");
Human[] humans = new Human[5];
humans[0] = new Man("李逵", 24);
humans[1] = new Man("松江", 44);
humans[2] = new Man("晁盖", 4);
humans[3] = new Woman("金莲", 24);
humans[4] = new Woman("王婆", 34);
for (int i = 0; i < humans.length; i++) {
if (humans[i].age > 23) {
System.out.println(humans[i].name + "=====" + humans[i].age);
}
}
}
}
abstract class Human {
String name;
int age;
public Human() {
super();
}
public Human(String name, int age) {
super();
this.name = name;
this.age = age;
}
public abstract void eat();
public abstract void work();
}
class Man extends Human{
public Man() {
super();
}
public Man(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("男人最喜欢吃烤串、火锅");
}
@Override
public void work() {
System.out.println("男人吃好了工作才能更好");
}
}
class Woman extends Human{
public Woman() {
super();
}
public Woman(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("女人最喜欢吃火锅、甜点");
}
@Override
public void work() {
System.out.println("女人吃好了才能更好的减肥");
}
}
八、今日总结
1、static(重点)
修饰变量
修饰方法
修饰代码块
2、代码块(重点)
局部代码块
构造代码块
静态代码块
3、final(重点)
修饰变量
修饰方法
修饰类
4、抽象(重点)
什么是抽象
抽象方法
抽象类
5、对象数组(熟练)