Java学习day_10之面向对象进阶(static&继承)
·
一、static
static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量
1.被static修饰的成员变量,叫做静态变量
特点:
- 被该类所有对象共享
- 不属于对象,属于类
- 随着类的加载而加载,优于对象存在
调用方式:
- 类名调用(推荐)
- 对象名调用
代码示例:
public class Student {
private String name;
private int age;
private String gender;
public static String teacher;
public Student(){
}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void study(){
System.out.println(name + "正在学习");
}
public void show(){
System.out.println(name + ", " + age + ", " + gender + ", " + teacher);
}
}
public class StudentTest {
public static void main(String[] args) {
Student.teacher = "阿玮";
Student s1 = new Student();
s1.setName("张三");
s1.setAge(23);
s1.setGender("男");
s1.study();
s1.show();
Student s2 = new Student();
s2.setName("李四");
s2.setAge(24);
s2.setGender("女");
//s2.teacher = "阿玮";
s2.study();
s2.show();
}
}

2.被static修饰的成员方法,叫做静态方法
特点:
- 多用在测试类和工具类中
- Javabean类中很少会用
调用方式:
- 类名调用(推荐)
- 对象名调用
- Javabean类:用来描述一类事物的类。比如,Student,Teacher,Dog等
- 测试类:用来检查其他类是否书写正确,带有main方法的类,是程序的入口
- 工具类:不是用来描述一类事物的,而是做一些事情的类,一般要求:类名见名知意;私有化构造方法;方法定义为静态
工具类代码示例:
需求:
1.提供一个工具类方法printArr,用于返回整数数组内容
2.提供一个工具类方法getAverage,用于返回平均分
public class ArrayUtil {
//私有化构造方法
//目的:为了不让外界创造对象
private ArrayUtil(){
}
//需要定义为静态的,方便调用
//返回整数数组内容
public static String printArr(int[] arr){
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i != arr.length - 1){
sb.append(arr[i]).append(",");
}else{
sb.append(arr[i]);
}
}
sb.append("]");
return sb.toString();
}
//返回平均分
public static double getAverage(double[] arr){
double sum = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum + arr[i];
}
return sum/arr.length;
}
}
public class TestDemo {
public static void main(String[] args) {
//测试工具类
int[] arr = {1,2,3,4,5};
String str = ArrayUtil.printArr(arr);
System.out.println(str);
double[] arr1 = {1,2,3,4,5};
double result = ArrayUtil.getAverage(arr1);
System.out.println(result);
}
}

public class Student {
String name;
int age;
static String teacherName;
//this:表示当前方法调用者的地址值
//此this是由虚拟机赋值的
public void show1(Student this){
System.out.println("this:" + this);
System.out.println(this.name + ", " + this.age + ", " + teacherName);
//调用其他方法
this.show2();
}
public void show2(){
System.out.println("show2");
}
public static void method(){
System.out.println("静态方法");
}
}
public class StudentTest {
public static void main(String[] args) {
Student.teacherName = "阿玮老师";
Student s1 = new Student();
System.out.println("s1:" + s1);
s1.name = "zhangsan";
s1.age = 23;
s1.show1();
System.out.println("************************");
Student s2 = new Student();
System.out.println("s2:" + s2);
s2.name = "lisi";
s2.age = 24;
s2.show1();
}
}

static的注意事项
- 静态方法只能访问静态变量和静态方法
- 非静态方法可以访问所有
- 静态方法中没有this关键字
1.静态方法不可访问非静态的方法和变量
2.静态方法中不能有this关键字
3.重新认识main方法
public class StudentTest {
public static void main(String[] args) {
}
}
public:被JVM调用,访问权限足够大。
static:被JVM调用,不用创建对象,直接类名访问;
因为main方法是静态的,所以测试类中其他方法也需要是静态的。
void:被JVM调用,不需要给JVM返回值。
main:一个通用的名称,虽然不是关键字,但是被JVM识别。
String[] args:以前用于接受键盘录入数据,现在弃用。
二、继承
概念: Java继承是面向对象编程的核心特性之一,允许一个类(子类/派生类)基于另一个类(父类/基类)构建,继承父类的属性和方法。通过继承,子类可以直接复用父类的代码,同时可以扩展或修改父类的功能,实现代码复用和层次化设计。
格式:
public class Student extends Person() {}
Student称为子类,Person称为父类
注:
- Java只能单继承:一个类只能继承一个直接父类。
- Java不支持多继承、但是支持多层继承。
- Java中所有的类都直接或者间接继承于Object类
1.子类可以继承父类的内容
| 非private | private | |
|---|---|---|
| 成员变量 | 能 | 不能 |
| 成员方法 | 能 | 不能 |
| 构造方法 | 不能 | 不能 |
class Parent {
public int publicVar;
protected int protectedVar;
int defaultVar; // 同包可见
private int privateVar; // 子类不可见
public void publicMethod() {}
protected void protectedMethod() {}
void defaultMethod() {} // 同包可见
private void privateMethod() {} // 子类不可见
}
class Child extends Parent {
void useInheritedMembers() {
publicVar = 1; // 可访问
protectedVar = 2; // 可访问
defaultVar = 3; // 仅当与Parent同包时可访问
publicMethod(); // 可访问
protectedMethod(); // 可访问
defaultMethod(); // 仅当与Parent同包时可访问
// privateVar = 4; // 编译错误,不可访问
// privateMethod(); // 编译错误,不可访问
}
}
2.继承中成员变量的访问特点
遵循就近原则:先从局部位置找,再从本类成员位置找,然后父类成员位置找,逐级往上。
//重名变量情况:
System.out.println(name); //从局部位置开始找
System.out.println(this.name); //从本类成员位置开始找
System.out.println(super.name); //从父类成员位置开始找
3.继承中成员方法的访问特点
this调用:就近原则;super调用:直接找父类
方法重写:在继承体系中,子类出现和父类种相同的方法声明,称子类的这个方法是重写方法,一般建议加上@Override注解可以检验重写是否正确,同时可读性好。方法重写的本质是覆盖虚方法表中的方法
基本要求:
- 子类重新的方法尽量跟父类保持一致
- 只有虚方法表里面的内容可以被重写
虚方法表:
- JVM 会为每个类编译生成一个虚方法表,表中存储该类所有可被重写的方法(即非private、非static、非final的方法)的入口地址。
- 方法表的继承与重写
子类的虚方法表会继承父类的虚方法表结构。
如果子类重写了父类的某个方法,子类方法表中该方法的地址会被替换为子类重写后的方法地址。
子类新增的方法会被追加到方法表的末尾。- 运行时的方法查找
当通过对象引用调用方法时,JVM 会先获取该对象的实际类型对应的虚方法表。
根据方法在表中的索引(编译时确定),直接找到并执行对应的方法地址,无需在运行时逐个检查类型,提高效率。
示例:
class Animal {
public void eat() { System.out.println("Animal eats"); }
public void sleep() { System.out.println("Animal sleeps"); }
}
class Dog extends Animal {
@Override
public void eat() { System.out.println("Dog eats meat"); }
public void bark() { System.out.println("Dog barks"); }
}


4.继承中构造方法的访问特点
- 子类不能继承父类的构造方法,但是可以通过super调用
- 子类构造方法的第一行,有一个默认的super();
- 默认先访问父类中无参的构造方法,再执行自己。
- 如果想要方法访问父类有参构造,必须手动书写。
public class Employ {
private String id;
private String name;
private int salary;
public Employ() {
}
public Employ(String id, String name, int salary) {
this.id = id;
this.name = name;
this.salary = salary;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public void work(){
System.out.println("工作");
}
public void eat(){
System.out.println("吃米饭");
}
}
public class Manager extends Employ{
private double manageSalary;
public Manager() {
}
public Manager(String id, String name, int salary, double manageSalary) {
super(id, name, salary);
this.manageSalary = manageSalary;
}
public double getManageSalary() {
return manageSalary;
}
public void setManageSalary(double manageSalary) {
this.manageSalary = manageSalary;
}
@Override
public void work() {
System.out.println("管理其他人");
}
}
public class Test {
public static void main(String[] args) {
Manager m = new Manager("001","zhangsan",15000,8000);
System.out.println(m.getId() + ", " +m.getName() + ", " + m.getSalary() + ", " + m.getManageSalary());
m.work();
m.eat();
}
}

5.this、super使用总结
| 关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
|---|---|---|---|
| this | this.成员变量(访问本类成员变量) | this.成员方法(…)(访问本类成员方法) | this(…) (访问本类其他构造方法) |
| super | super.成员变量(访问父类成员变量) | super.成员方法(…)(访问父类成员方法) | super(…) (访问父类构造方法) |
更多推荐



所有评论(0)