关于面向对象编程
暑假预习Java,这里总结下面向对象中Java和C++一些不一样的地方
super();
class person {
protected int age;
public person(int age) {
this.age = age;
}
}
class student extends person {
protected int score;
public student(int age,int score) {
//super(age);
this.score = score;
}
}
如果没有使用super,会得到一个编译错误,在student的构造方法中,无法调用person的构造方法
在java里,任何class的构造方法,第一行必须调用父类的构造方法,如果没有明确地调用父类的构造方法,编译器会自动加一句super();
,but,这个super里没有参数,父类里没有无参数的构造方法,故编译失败,因此,需要把注释去掉,加上正确的super语句
阻止继承
官方版
aa.java
public final class aa{/* code */}
用final
来修饰指定类
bb.java
public class bb extends aa{/* code */}
编译完第一个类后再编译第二个类,JDK编译器会报错,编译器会在extends处提示错误
非官方版
aa.java
public class aa{
private aa(){/**/}
public static aa fun(){
return new aa();
}
}
Java在继承时必须在构造器里的第一行调用super class的构造器。当父类构造器设为private权限时,其他类继承这个类时,编译器会尝试调用一个默认的super构造器,而super构造器时private的,就不能被调用,也就是不能被继承。
多态
aa.java
public class aa{
public static void main(String[] args){
person p = new student();
p.run();
//result: student.run
}
}
class person{
public void fun(){
System.out.println("person.run");
}
}
class student{
@override
//override后面不要加分号
public void fun(){
System.out.print("student.run");
}
}
下面是一个报税的例子
public class aa {
public static void main(String[] args) {
income[] incomes = new income[] { new income(3000), new salary(7000), new allowance(10000) };
System.out.println(totalTax(incomes));
//打印的结果是income,salary,allowance折扣后的总值
}
public static double totalTax(income... incomes) {
double total = 0;
for (income in : incomes) {
total += in.getTax();
}
return total;
}
}
class income {
//收入
protected double in;
public income(double in) {
this.in = in;
}
public double getTax() {
return in * 0.1;
}
}
class salary extends income {
//工资
public salary(double in) {
super(in);
}
@Override
public double getTax() {
if (in <= 5000)
return 0;
return (in-5000)*0.2;
}
}
class allowance extends income {
//特殊津贴
public allowance(double in) {
super(in);
}
@Override
public double getTax() {
return 0;
}
}
调用super
class person{
protected String name;
public String hello(){
return "hello, " + name;
}
}
class student extends person{
@override
public String hello(){
//调用父类的hello()方法
return super.hello() + "!";
}
}
final
class aa{
public final String fun(){/**/}
}
class bb{
@override
public String fun(){/**/}
//父类成员用final修饰,子类不能重写
//final修饰类,类不能被继承,final修饰变量,变量必须初始化
}
抽象类
//定义一个抽象类
class person{
public abstract void fun();
}
把一个方法声明为abstract,提示编译错误,无法编译person类,因为它包含抽象方法,所以必须把person也声明为abstract,这就叫抽象类
abstract class person{
public abstract void fun();
}
但是,对于person类,我们无法使他实例化,即在main中执行person p = new person();
因此,抽象类一般被设计来继承
public class aa {
public static void main(String[] args) {
person p = new student();
person t = new teacher();
p.fun();
t.fun();
}
}
abstract class person {
public abstract void fun();
}
class student extends person {
@Override
public void fun() {
System.out.println("student.fun");
}
}
class teacher extends person{
@override
public void fun(){
System.out.println("teacher.fun");
}
}
如上例子,person定义了抽象方法fun()
,那么在实现子类时,就必须覆写run()
面向对象编程
刚才定义了抽象类person()
,以及具体的student、teacher的子类,我们可以通过抽象类person去引用具体的子类
person s = new student();
person t = new teacher();
这种引用抽象类的好处在于,我们调用其方法,并不关心person类型变量的具体子类型
s.fun();
t.fun();
同样的,我们再用用一个新的子类,我们仍不关心具体类型。
因此,这种尽量引用高层类型,避免引用实际子类型的方式,叫面向对象编程
三个本质
- 上层代码只定义规范(例如
abstract class person;
); - 不需要子类就可以实现业务逻辑(正常编译)
- 实现的业务逻辑由不同的子类实现,调用者并不关心
一个java文件里只能有一个public类
感觉我的面向对象编程是在Java里学的