针对某一个变量属于类而不属于某一个具体的对象的时候,我们可以考虑使用static关键字。
1.static修饰变量又称为共享变量,类变量,静态变量
2.静态成员属于某一类的,而不属于某一个具体的对象,简单来说只要类被加载了,就可以通过类名直接去进行访问被static修饰的变量或方法。
3.访问静态成员的方式:Ⅰ可以通过对象访问但不建议 Ⅱ通过类名访问 Ⅲ通过读写方法访问
4.静态的资源在类初始化的时候就加载了
static修饰的方法称为类方法,方法体内部称为静态环境/静态上下文
需要注意的是:非静态环境可以访问静态变量,但是静态环境下只能够访问静态变量,且静态环境下不能够出现this,super。
static是共享的,不变的,放在方法区,静态代码块在类加载的时候就会执行,并且只执行一次
public class StaticDemo01 {
public static void main(String[] args) {
Student.country = "中国";
Student s1 = new Student("张三", 18);
// s1.country = "中国";
Student s2 = new Student("李四", 20);
Student s3 = new Student();
s1.show();
s2.show();
s3.show();
s2.country = "美国";
s1.show();
s2.show();
s3.show();
Student.staticMethod();
// s1.staticMethod();
}
}
class Student {
String name;
int age;
static String country;
static class InnerClass {
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
}
public Student(String name, int age, String country) {
super();
this.name = name;
this.age = age;
Student.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show() {
System.out.println("Student [name=" + name + ", age=" + age + ",country=" + country + "]");
}
// public String getCountry() {
// return country;
// }
public static String getCountry() {
// System.out.println(this.name);
return country;
}
public static void setCountry(String country) {
Student.country = country;
}
public static void staticMethod() {
System.out.println("Student.staticMethod()");
}
}
从这里可以看出static修饰的变量是共享的,当更改之后所有的对象中的country都发生了变化。
1.局部代码块: 定义在局部位置,限定局部变量的作用域
2.构造代码块: 定义在成员位置,抽取多个构造代码块的重复代码,从而简化代码,在每次构造方法之前执行,并且可以执行多次
3.静态代码块: 定义在成员位置,在类加载的时候执行,只能够执行一次
静态代码块的作用:
a.初始化静态成员
b.资源文件的读写,以及配置文件的读写,以及连接资源的载入,和数据库连接
4.同步代码块: 定义在局部位置
public class Test02 {
public static void main(String[] args) {
CodeBlock.z = 100;
CodeBlock cb = new CodeBlock();
CodeBlock cb2 = new CodeBlock(1, 2);
}
}
class CodeBlock {
int x;
int y;
static int z;
{
System.out.println("CodeBlock 构造代码块");
print();
}
public CodeBlock() {
// print();
System.out.println("我是无参构造方法");
}
static {
System.out.println("我是静态代码块");
z = 100;
}
public CodeBlock(int x, int y) {
// print();
this.x = x;
this.y = y;
System.out.println("我是带参构造方法");
}
public void print() {
System.out.format("(%d,%d)%n", x, y);
}
public void method() {
int num = 10;
// 局部代码块
{
int a = 20;
System.out.println(num);
System.out.println(a);
}
int a = 30;
// 同步代码块
synchronized(new Object()){
}
}
}
类是对一批对象的抽象,继承是对一批类的抽象
1.一般在写代码的时候发现代码中存在重复代码,需要向上抽取,考虑继承
2.当某个类的设计非常复杂的时候可以考虑继承 例如: 设计一个窗口类
通过extends关键字可以实现类与类的继承
class 子类类名 extends 父类类名 {
}
被继承的这个类称为父类,基类或者超类
继承的这个类称为子类或者派生类
1.继承的本质就是抽取共性代码,多个重复代码的向上抽取,简化代码 BaseDao BaseActivity
2.父类又被称为超类,或者基类,子类又被称为派生类
3.Java是面向对象语言,万事万物皆是对象,为了满足这个设计原则,所有的类都直接或者间接继承自Object类
1.简化了代码
2.提高了扩展性
3.提高了可维护性
继承的使用要注意高内聚,低耦合: 类与类之间,功能与功能之间,模块与模块之间,功能尽量内聚,不同模块之间,尽量独立,如造成了耦合性过高,则牵一发动全身
1.单一继承性
2.支持多层继承
3.如果父类成员使用private修饰,那么子类不能被继承
4.如果一个子类继承了父类的属性和方法还可以有自己特有的属性和方法
5.当子类和父类的成员变量重名的时候,子类优先
6.构造方法不能够被继承
import javax.swing.JFrame;
public class Test03 {
public static void main(String[] args) {
PrimaryStudent ps = new PrimaryStudent();
ps.play();
MyFrame frame = new MyFrame();
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setTitle("HelloWorld");
frame.setVisible(true);
}
}
class MyFrame extends JFrame {
//设计一个窗口类时直接继承 Java 的Jframe
}
//如下面的的students类就抽取了,小学生,中学生,大学生的共同点
class Students extends Person{
private String name;
int age ;
String gender;
double money;
public Students() {}
public void payMoney(double money) {
this.money = money;
}
}
class Person extends Object {}
// 小学生类
class PrimaryStudent extends Students {
private String address;
private int age = 10;
public void play() {
int age = 20;
System.out.println("PrimaryStudent.play()");
System.out.println(age);
}
}
// 中学生类
class MiddleStudent extends Students {
public void study() {
System.out.println("MiddleStudent.study()");
}
}
// 大学生类
class CollegeStudent extends Students {
public void sleep() {
System.out.println("BigStudent.sleep()");
}
}
this可以理解为当前对象,谁调用this就代指那个调用者对象, 每次创建一个对象,默认都会创建一个this变量指向同一个堆区空间
super本质是父类存储空间的标识,但是你可以理解为父类对象,那么同样可以使用super这个关键字来访问父类的成员
1.任何一个类的无参或者带参构造方法的第一句都默认省略 super()。
2.任何一个类都直接或者间接继承自Object类。
3.super访问父类带参构造方法,帮助子类初始化父类继承下来的成员,简化编程
4.静态环境/静态上下文(static修饰的方法),不能够出现this和super
5.super必须出现在构造方法的第一句
6.this和super不能够共存
public class SuperDemo01 {
public static void main(String[] args) {
// Zi zi = new Zi();
// Zi zi = new Zi("张三", 18, "北京西路");
Fu fu = new Fu();
System.out.println(fu.name + "|" + fu.age);
/*
* 我是父类带参构造方法
* 我是父类无参构造方法
* "王五" 20
*/
}
}
class Fu extends Object {
public String name;
public int age;
private double weight;
public Fu() {
super();
// this("王五", 20);
System.out.println("我是父类无参构造方法");
}
public Fu(String name, int age) {
System.out.println("我是父类带参构造方法");
this.name = name;
this.age = age;
}
public void fuMethod() {
}
public static void staticMethod() {
}
}
class Zi extends Fu {
private String address;
public Zi() {
super();
System.out.println("我是子类无参构造方法");
}
public Zi(String name, int age, String address) {
// super();
// System.out.println("我是子类带参构造方法");
// this.name = name;
// this.age = age;
super(name, age);
this.address = address;
}
public void ziMethod() {
System.out.println(super.name);
this.fuMethod();
super.fuMethod();
}
}