目录
1. 继承
1.1 父类和子类
使用同一类对同一类型的对象进行建模,不同的类也可能会有一些共同的特征,这些共同的特征又可以放在一个类中,这个类就叫父类。
例如:父类为几何图形,几何图形的特征有1.颜色 2.是否被填充 3.创建日期。子类有圆,圆的特征有1.半径 2.周长 3.面积。字类还有正方形,正方形特征有1.边长 2.周长 3.面积。
子类继承了父类的所有可访问的数据域和方法,除此之外,每个子类还有其特有的数据域和方法
子类并不是父类的一个子集,实际上,子类通常比父类包含更多的信息和方法
父类和子类的关系为“是一种”,即圆是一种几何图形,正方形是一种几何图形
某些程序语言允许几个类派生出一个子类,称为多重继承,但Java中只允许一个父类,称为单一继承
class Geometry{
private String color;
private boolean filled;
private java.util.Date dateCreated;
public Geometry(){
}
public Geometry(String color,boolean filled){
this.color = color;
this.filled = filled;
}
public String getColor(){
return color;
}
public void setColor(String color){
this.color = color;
}
public boolean isFilled(){
return filled;
}
public void setFilled(boolean filled){
this.filled = filled;
}
public String getDate(){
return dateCreated;
}
}
class Circle extends Geometry{
private double r;
public Circle(){
}
public Circle(double r,String color,boolean filled){
this.r = r;
setColor(color);
setFilled(filled);
}
public double getR(){
return r;
}
public void reSetR(double r){
this.r = r;
}
public double getAre(){
return Math.PI * r * r;
}
}
上述Circle为Geometry的子类,可以直接用setColor()和setFilled()方法
1.2 super关键字
super()用来调用父类的构造方法
例如1.1中代码
setColor(color);
setFilled(filled);
可以用super(color,filled);来替换
super.name()可以用来调用父类的方法
1.3 构造方法链
如果直接调用一个子类的构造方法,系统会自动先调用父类的无参构造方法,例如:
public class Name{
//原本是这样写的
}
public class Name{
super();
//系统会自动添加一个super()来调用父类的构造方法
}
所以有时候可以不在子类的构造方法里写super(),但有时必须得写,例如:
class A{
public A(int x){
}
}
class B extends A{
public B(){
//1处
}
}
class C{
public static void main(String[] args){
B b = new B();
}
}
此代码会编译错误,main方法中调用创建了一个B类,创建B类时,因为B是A的子类,系统发现没有主动写super(),所以会在1处自动加一个super()来调用父类的构造方法,但父类A的构造方法需要参数,所以会编译错误。
正确代码:
class A{
public A(int x){
}
}
class B extends A{
public B(){
super(5);
}
}
class C{
public static void main(String[] args){
B b = new B();
}
}
编译通过
1.4 重写与重载
1.4.1 重载
public class Main{
public static void main(String[] args){
A a = new A();
a.p(10);
a.p(10.0);
}
}
class B{
public void p(double i){
System.out.println(i * 2);
}
}
class A extends B{
public void p(int i){
System.out.println(i);
}
}
输出为
10
20.0
对于方法p,在父类B和子类A中都有同样的方法p,但二者的参数列表不同,一个为int另一个为double,这样称为重载
调用方法p时,系统检测第一个10为int,调用A类的p方法
系统检测第二个10.0为double,调用类B的p方法
1.4.2 重写
public class Main{
public static void main(String[] args){
A a = new A();
a.p(10);
a.p(10.0);
}
}
class B{
public void p(double i){
System.out.println(i * 2);
}
}
class A extends B{
public void p(double i){
System.out.println(i);
}
}
输出为
10.0
10.0
对于方法p,在父类B和父类A中都有,并且完全相同,这样称为重写。
对于A类型的a,调用p方法时,调用的是A类中的p方法
对于B类型的a,调用p方法时,调用的时B类中的p方法
1.4.3重写和重载
1.重写发生在通过继承关联的不同类中。重载可以在同一类中,也可以在通过继承关联的不同类中
2.重写方法必须完全相同,重载方法可以有不同的返回值和不同的参数列表
1.4.4重写标注
为了避免错误,可以在重写的方法前加一个@Override
public class Main{
public static void main(String[] args){
A a = new A();
a.p(10);
a.p(10.0);
}
}
class B{
public void p(double i){
System.out.println(i * 2);
}
}
class A extends B{
@Override
public void p(double i){
System.out.println(i);
}
}
加上@override后系统会自动检查是不是重写方法,如果不是则会编译错误
1.5 Object类和toString()方法
如果一个类在定义时没有指定继承,则默认继承Object类
public class Name{
;
}
默认为:
public class Name extends Object{
;
}
Object类中的toString()方法,返回一个描述该对象的字符串:类名+@+该对象地址
2. 多态
2.1 多态
子类继承父类的特征,在传参时可以将子类传给父类类型定义的参数
例如:1处所示
public class Main{
public static void main(String[] args){
display(new Grandson());
display(new Son());
display(new Father());
//display(new Object()); 错误,因为Objcet为Father的父类,不能这样传参
}
public static void display(Father x){ //1处
System.out.println(x.toString());
}
}
class Father extends Object{
@Override
public String toString(){
return "Hello1";
}
}
class Son extends Father{
@Override
public String toString(){
return "Hello2";
}
}
class Grandson extends Son{
@Override
public String toString(){
return "Hello3";
}
}
2.2 动态绑定
2.1中输出为
Hello3
Hello2
Hello1
display(new Grandson()); JVM会依次在Grandson中、Son中、Father中、Object中寻找toString()方法,找到就调用
display(new Son()); JVM会依次在Son中、Father中、Object中寻找toString()方法,找到就调用
display(new Father()); JVM会依次在Father中、Object中寻找toString()方法,找到就调用
public class Main{
public static void main(String[] args){
display(new Grandson());
display(new Son());
display(new Father());
display(new Object());
}
public static void display(Object x){
System.out.println(x.toString());
}
}
class Father extends Object{
@Override
public String toString(){
return "Hello1";
}
}
class Son extends Father{
}
class Grandson extends Son{
@Override
public String toString(){
return "Hello3";
}
}
输出为
Hello3
Hello1
Hello1
java.lang.Object@1f32e575
2.3 对象转换
永远可以将子类转换为父类,称为向上转换
不可以直接将父类转换为子类,称为向下转换
Object o = new Father();//向上转换
Father p = o;//向下转换 不行
Father p = (Father) o;//向下转换 行
3. ArrayList类
3.1 ArrayList类UML图
在使用remove(index)后,所有index后的元素会自动往前移一位
ArrayList类重写了Object类的toString()方法,以字符串型返回数组的全部内容
3.2 ArrayList类方法
对数组排序:Arrays.sort(arr);
对ArrayList排序:Collections.sort(list);
返回ArrayList最大最小值:
Collections.max(list);
Collections.min(list);
3.3 ArrayList和数组相互转换
list -> arr
String[] arr = {"a","b","c","d"};
ArrayList<String> list = new ArrayList<String>(Arrays.asList(arr));
arr -> list
String[] arr = new String[list.size()];
list.toArray(arr);
4. protected数据和方法
private、public、protected都是可见性修饰符,被它们修饰的数据或方法有如下特点:
被private修饰:仅能在当前类中访问和调用
无修饰:仅能在当前包内被访问和调用
被protected修饰:可在当前包内或包外的子类访问和调用
被public修饰在哪都可以被访问和调用
由上到下访问性逐渐增强
另外:
在重写的时候,子类不能削弱父类的可访问性,但可以增强访问性
5. final修饰符
用final修饰后的类无法被继承,无法成为一个父类
用final修饰后的方法不能被重写
public final class A{
}
public class Test{
public final void test(){
}
}
这里的类A无法被继承,test方法无法被重写