面向对象 面向对象编程有三大特性:封装、继承、多态。
类的封装 类的封装十分简单,就是创建一个类,将类的功能写完,供别的类实例化调用即可,他的作用就是隐藏功能的细节,仅提供功能,如以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class Func { public int mul (int a, int b) { int sum = 0 ; for (int i = 0 ; i < b; i++) { sum += a; } return sum; } } public class main { public static void main (String[] args) { Func func = new Func(); System.out.println(func.mul(3 ,2 )); } }
这个封装的类Func功能就是将两个数相乘,但是只看主函数是不知道Func是如何将两个数相乘的,有可能是直接return a * b,也有可能像上面一样,所以封装的类是隐藏了实现细节的。
类的继承 如果我现在想创建一个类,而且已经有一个现成的类具备了部分我想创建的类的功能,那我就可以直接继承他的所有功能,并且还可以额外增加自己的功能。
继承的关键字是extends,如果你想继承一个类,写法是这样的:
1 2 3 class zi extends fu { }
这样就继承了fu类,zi可以用fu类的功能,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Fudemo { public void Fu () { System.out.println("这是父类方法" ); } } public class Zidemo extends Fudemo { public void Zi () { System.out.println("这是子类方法" ); } } public class main { public static void main (String[] args) { Zidemo zi = new Zidemo(); zi.Fu(); zi.Zi(); } }
方法重写 如果我想在子类里写一个和父类名称相同的方法,这种操作叫做重写。
要注意一点,重写的方法修饰权限必须要比原方法一致或更高。 而返回值类型必须与原方法范围一致或更小。
1 2 3 4 5 6 7 8 9 10 public class Zidemo extends Fudemo { public void Zi () { System.out.println("这是子类方法" ); } @Override public void Fu () { System.out.println("这是重写父类方法" ); } }
我们重写了Fu方法,这样我们用zi.Fu()调用时就会调用我们重写的方法,
@override是注解,在重写方法前写上可以检验重写是否正确(但是不写注解不影响执行)。
那我们在重写了方法后,还可以使用原方法吗?用super关键字就可以。
1 2 3 4 5 6 7 8 9 10 11 public class Zidemo extends Fudemo { public void Zi () { System.out.println("这是子类方法" ); } @Override public void Fu () { super .Fu(); System.out.println("这是重写父类方法" ); } }
这样我们就会在重写方法前调用原Fu方法:
用super还可以调用父类的参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Fudemo { int num = 10 ; public void Fu () { System.out.println("这是父类方法" ); } } public class Zidemo extends Fudemo { int num = 20 ; public void Zi () { System.out.println("这是子类方法" ); } @Override public void Fu () { System.out.println(super .num); System.out.println(num); System.out.println("这是重写父类方法" ); } }
可以看到结果:
tips:object类是所有类的父类,我们写类的时候无需写extends object
类的多态 重载 重载非常简单,即为多个方法使用相同的方法名,根据传回的参数个数和类型不同调用不同的方法,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class adddemo { public int add (int a, int b) { return a + b; } public int add (int a, int b, int c) { return a + b + c; } public int add (int a, int b, int c, int d) { return a + b + c + d; } } public class main { public static void main (String[] args) { adddemo add = new adddemo(); System.out.println(add.add(1 ,2 )); System.out.println(add.add(1 ,2 ,3 )); System.out.println(add.add(1 ,2 ,3 ,4 )); } }
构成重载的条件:
参数类型不同
参数个数不同
不同类型参数顺序不同
向上转型 如果现在有一个方法的参数是a类的实例,b是a类子类,那么b类的实例也可以作为参数,因为子类完全具备父类的各种特征,如平行四边形完全符合四边形的定义。
向下转型 四边形不一定是平行四边形,所以我们要先进行检验他是不是平行四边形,我们要用到的关键字是instanceof,这个关键字可以检验一个实例对象是否属于一个类大概用法:
如果A是的话,我们还要进行一步强制转换类型,就可以了:
1 平行四边形 平行四边形A = (平行四边形) 四边形A;
抽象类 四边形可以是一个具体的类吗?平行四边形、矩形、梯形这些都可以是四边形的具体类,那么我们可以把四边形定义为一个抽象类,这个类的意义就是被继承,他里面的所有方法都没有任何代码,只有方法名和参数,他的意义也只是被重写。
定义一个抽象类的关键字是abstract,
1 2 3 abstract class classdemo { public abstract void func1 (int a. int b) ; }
这样的类的唯一意义就是被继承,而且继承自他的子类必须重写里面的所有用abstract关键字的方法。
接口 一个类不能有多个父类,如果抽象类中有我用不到的方法,那我也只能重写,如果拿出去的话,我不能继承两个类,这时候接口就十分有用。
接口用interface定义:
1 2 3 4 interface 接口名 [extends 父接口名1,父接口名2]{ public [static 或 final ] 常量; public abstract 方法; }
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public interface Father { void smoking () ; void fishing () ; } public interface Mother { void cooking () ; void watchTV () ; } public class son implements Father , Mother { @Override public void smoking () { System.out.println("我爱抽烟" ); } @Override public void fishing () { System.out.println("我爱钓鱼" ); } @Override public void cooking () { System.out.println("我爱做饭" ); } @Override public void watchTV () { System.out.println("我爱看电视" ); } } public class main { public static void main (String[] args) { son son1 = new son(); son1.cooking(); son1.fishing(); son1.smoking(); son1.watchTV(); } }
可见接口可以继承多个,儿子继承了Father和Mother接口。
那么抽象类和接口除了继承一个和继承多个以外还有什么区别呢?
抽象类
接口
方法
可以有非抽象方法
全为抽象方法
属性
可以有非静态常量
全为静态常量
构造方法
有
无
未完待续。。。