重拾Java (四)类和对象(面向对象)
2019-02-24 本文已影响0人
h2coder
重拾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
}
}