Java:对类和对象进一步认识,static和继承

static

public class Cat {
    public static String CatName= "咪咪";
}

我们可以观察如上代码,CatName被static修饰,此时它就变成了静态变量,它将不在存在于对象当中,我们可以通过类名.进行访问。静态成员的使用不依赖于对象,不通过对象引用。同样,我们可以定义静态成员方法。同时我们要注意,静态方法内部不能直接调用非静态方法,也不能调用this。

public static void main(String[] args) {
    System.out.println(Cat.CatName);
}

静态方法不属于某个具体的方法,属于类方法,同样需要通过类名去调用。

代码块

成员变量除了可以像上面一样就地初始化,也可以通过代码块进行初始化。由{}定义的代码叫做代码块。代码块分为普通代码块,实例代码块(也叫构造代码块),静态代码块等。

首先我们介绍实例代码块,它可以对普通成员变量进行初始化,如下

public class Student {
    private String name;
    private int age;
    private int id;
    {
        this.name="张三";
        this.age=18;
        this.id=001;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }

}
class Test{
    public static void main(String[] args) {
        Student student=new Student();
        System.out.println(student.toString());
    }
}

这样可以初始化成员变量

同样,静态成员变量也可以这样进行初始化,这就称为静态代码块

public class Student {
    public static int classroom;
    static{
        classroom=100;
    }
}
class Test{
    public static void main(String[] args) {
        System.out.println(Student.classroom);
    }
}

实例代码块比构造方法率先执行,只有有对象时才会执行。而静态代码块儿比实例代码块儿更早执行,静态代码块只执行一次,多个静态代码块儿谁写在前面谁就先执行,看定义的顺序,只要类被加载就会执行。此外,我们可以在上述代码中看到toString这样一个方法。这个方法可以帮助我们便捷的打印。

继承

我们曾经定义过小猫、小狗这样的类,那么下面我们来定义一个动物的类。动物都会有自己的名字,年龄,都会进行吃饭这一行为,那么我们可以快速的定义出这样一个animal类。

class animal{
    private String name;
    private int age;
    public static void  eat(){
        System.out.println("吃饭。");
    }
}

那么小猫小狗都是动物,它们都拥有动物的特性。那么我们是否可以把这些类当中的共性抽取进行代码的复用呢?也就是说我们能不能仅仅定义一个animal类的代码,之后我们再定义小猫小狗更多其他小动物的时候,简化我们定义相同成员变量或成员方法时的代码。使代码看起来更加简洁。也更加方便易懂。答案是可以的,这就是我们所谓的继承。

我们可以通过继承来实现代码的复用。把类当中的共性抽取进行代码的复用,一定是子类的共性,子类继承后必须要新添加自己独有的成员,体现出不同,否则就没有必要继承。子类和父类之间类似于一种is-a的关系。例如dog is a animal。(是an,但是懒得改)能实现这个关系的一般就可以继承。
我们可以使用extends关键字进行继承,这时我们再定义小狗类可以这样实现

class dog extends animal{
    private String color;
    public void bark(){
        System.out.println("汪汪叫");
    }
}

这样我们就实现了继承。

super

class Base{
    public int a;
    public int b;
}
class Derived extends Base{
    public void write(){
        a=10;
        b=20;
    }
    public int c=30;
}

我们可以观察如上代码。当我们执行write这个方法,我们访问的a变量是父类的a变量还是子类的a变量呢?答案是子类的。
当子类和父类变量同名时,同名的成员变量在子类当中访问同名成员变量,优先访问子类自己的如果一定要访问父类的变量,就要用到另一个关键字super。

class Derived extends Base{
    public void write(){
        super.a=10;
        b=20;
    }
    public int c=30;
}

这个时候我们访问的a便是父类的。父类的成员都可以用super访问。Super只能访问从父类继承过来的成员变量,super只是一个关键字,它与this不一样,它并不是对父类对象的引用。使用super可以提高代码的可读性,别人看到这样访问就知道是访问父类的关键字。
那么成员方法呢?成员方法的名字一样(方法的重载),先看参数都一样,应该是优先调用子类。调用父类同样要使用super。

当我们父类有构造方法时,当子类继承父类之后,一定要先帮助父类进行构造,再构造子类自己。只能在子类当中调用父类的构造方法。

class Derived extends Base{
    public void write(){
        super.a=10;
        b=20;
    }
    public int c=30;

    public Derived(int a, int b, int c) {
        super(a, b);
        this.c = c;
    }
}

此时相当于先帮助父类进行初始化操作。
如果一个类不想被继承,那就使用关键字final进行修饰。
public final class Animal{...}

这样将不能继承。

注意,java不支持多继承,即一个类继承了多个类,但允许一个类被多个类继承。

组合

组合可以表示对象之间是has a的关系,比如,学校由若干学生、老师组成,我们可以这么表示。

class student{
    public String name;
    public int age;
    public int id;
}
class teacher{
    public String name;
    public int age;
}
class School{
    public student[] students;
    public teacher[] teachers;

    public School(student[] students, teacher[] teachers) {
        this.students = students;
        this.teachers = teachers;
    }
}

我们后面进行组合这样的操作时,都可以这样操作。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值