美文网首页重拾Java
重拾Java (四)类和对象(面向对象)

重拾Java (四)类和对象(面向对象)

作者: h2coder | 来源:发表于2019-02-24 13:05 被阅读0次

重拾Java第四篇-类和对象

  • Java是面向对象的一门语言,类作为面向对象的第一公民,有必要学习一下啦~

  • 类的建立

    • 类使用class关键字标识,同样也支持访问修饰符
    • static标识这个是一个静态类
    • public表示该类是公开的
public class Person {

}
  • 类的字段
    • 字段则是类的成员变量,也可以说是类的属性
public class Person {
    //人类的2个属性
    private String name;
    private int age;
}
* static关键字修饰则是类的静态变量
public class Person {
    private static int sex = 1;

    private String name;
    private int age;
}
  • 类是单继承,接口是可以多继承的,类可以实现多个接口,但是只能有一个直接父类,间接父类是可以多个的

    • 间接父类指的是:孙类对于爷类来讲,例如WoMan是Female的子类,WoMan的父类是Female,Female的父类是Person。Person对于Woman来说就是一个间接父类
    • 这个关系是可以多重的,例如Java默认父类都是Object,那么Object也是WoMan的间接父类。
  • 类的方法

    • 方法则是类的行为,也有类方法和静态方法之分
public class Person {
    private static int sex = 1;

    private String name;
    private int age;

    //类方法,需要实例化才能调用
    public void sayHello() {
        System.out.println("sex: " + sex + " name: " + this.name + " age: " + this.age);
    }

    //static关键字修饰,则为静态方法,直接通过类名.方法名()即可调用
    public void sayHello() {
        System.out.println("sex:" + sex);
    }
}

面向对象

  • 面向对象的三大特性:封装、继承、多态

    • 封装,封装指的是类的属性私有化,对外开放Get\Set方法进行访问,保证类的数据改变是有道可循的。
    • 继承,通过派生子类,继承父类,进行类拓展和方法复写,进行复用。
    • 多态,子类对象以父类类型接收,复写父类方法,虽然类型是父类类型,但调用被子类复写的父类方法时,会调用子类的复写逻辑。能将类进一步进行抽象,具体行为有定义抽象类和定义接口。
  • 封装,如果是类中内部使用,成员变量和方法使用private访问修饰符修饰,如需要开放给外部调用赋值,一般会保持成员变量为private,对外提供一对get\set方法进行赋值。

    • 不单只是成员变量,对外提供设置方法,改变多个成员变量也是很常见的。
public class Person {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • 继承,当公用逻辑是公用时,抽取到父类,不同子类的行为不同时,再提供抽象方法或空实现方法让子类进行复写。
    • 继承使用extend关键字
public class Person {
    private String name;
    private int age;

    //...省略属性get\set方法

    public void eat() {
        System.out.println("吃米饭");
    }
}

public class Male extend Person {
    @Override
    public void eat() {
        System.out.println("吃汉堡包");
    }
}

public class Female extend Person {
    @Override
    public void eat() {
        //哈哈,这里开个玩笑,只是演示复写
        System.out.println("吃钱");
    }
}
* 私有方法不可被复写,如果访问修饰符为private则不能被子类复写
public class Person {
    private String name;
    private int age;

    //...省略属性get\set方法

    public void eat() {
        System.out.println("吃米饭");
    }

    private void showInfo() {
        System.out.println("name: " + this.name + " age: " + this.age);
    }
}

public class Female extend Person {
    //私有方法会报错,编译是不通过的
    @Override
    private void showInfo() {
    }
}
* final关键字修饰的方法,不可被重写
public class Person {
    private String name;
    private int age;

    //...省略属性get\set方法

    public final void pay() {
        System.out.println("独自去偷欢~");
    }
}

public class Female extend Person {
    //final修饰的方法不可重写,编译是不通过的
    @Override
    public final void play() {
    }
}
* 上面eat方法是public的,就是说外部也可以调用,那如果只想内部调用,并且能被复写,外部不能调用呢?
* 这样我们只需要将public修饰符改为protected就可以啦~
public class Person {
    private String name;
    private int age;

    //...省略属性get\set方法

    protected final void play() {
        System.out.println("独自去偷欢~");
    }
}

public class Female extend Person {
    @Override
    protected void play() {
        System.out.println("让你玩,回来打断你的狗腿!");
    }
}
* 抽象类,当父类需要调用一个公用行为的方法,但每个子类的行为不一致时,可以使用abstract关键字,成为抽象类,提供抽象方法,调用即可
//声明为抽象类
public abstract class Person {
    private String name;
    private int age;

    //...省略属性get\set方法

    //抽象方法必须使用abstract关键字修饰
    //存在abstract抽象方法的类必须为抽象了!
    protected abstract void makeMoney();
}

public class Male extend Person {
    //子类必须重写抽象方法
    @Override
    protected void makeMoney() {
        System.out.println("我去公司敲代码赚钱...");
    }
}

public class Female extend Person {
    @Override
    protected void makeMoney() {
        System.out.println("我去银行上班赚钱...");
    }
}
  • 多态
    • 子类复写父类方法,子类实例赋值给父类类型,调用父类方法,会调用子类复写后的方法
public class Person {
    private String name;
    private int age;

    //...省略属性get\set方法

    //提供一个默认实现
    protected void work() {
        System.out.println("我不会赚钱");
    }
}

public class Male extend Person {
    //复写方法
    @Override
    protected void work() {
        System.out.println("我去公司敲代码赚钱...");
    }
}

//创建子类实例,父类类型接收
Person p = new Female();
//我去公司敲代码赚钱...
p.makeMoney();
* 接口方式实现。接口使用inteface关键字。
* 接口和抽象类的区别是,接口中的方法都是抽象方法,而抽象类中可以有普通方法也可以有抽象方法,但是接口只有抽象方法。
* 补充一下
    - 接口中的方法,都是public的。所以接口的方法没法做到不被外部调用,要想被复写又不能外部调用,只能选择抽象类中定义了。
    - 接口中的变量,都是public static final的,所以接口中定义的成员,都是空开不可被复写,并且是类共享的成员。
public inteface IShopping {
    void shopping();
}

public class Person implements IShopping {
    private String name;
    private int age;

    //...省略属性get\set方法

    //这里如果不去实现IShopping接口的方法,则子类会强制复写
}

public class Female extend Person {
    //子类复写方法
    @Override
    protected void shopping() {
        System.out.println("我要去逛街街,买包包啦~");
    }
}

//子类实例,父类类型接受
Person p = new Female();
//会输出:我要去逛街街,买包包啦~
p.shopping();
* 接口方式实现多态,常用就是定义行为接口,隐藏实现,例如依赖注入进行解耦,测试时替换实现等。
* 由于类的直接父类只能有一个,所以父类的位置很宝贵,我们在做设计时,应优先考虑接口实现而非继承,多用组合少用继承,效果更佳喔~
  • 关于接口要补充的,上面其实有讲接口,这里再说一遍~
    • 接口中的方法,都是public的。所以接口的方法没法做到不被外部调用,要想被复写又不能外部调用,只能选择抽象类中定义了。
    • 接口中的变量,都是public static final的,所以接口中定义的成员,都是空开不可被复写,并且是类共享的成员。
    • 在Java8一下,接口是不能有实现的,但是Java8开始,接口可以有默认实现了
public inteface IShopping {
    void shopping();

    //Java8开始支持在接口中写实现了
    void pay() {
        //...do something
    }
}

相关文章

网友评论

    本文标题:重拾Java (四)类和对象(面向对象)

    本文链接:https://www.haomeiwen.com/subject/zugvyqtx.html