Java面向对象2

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方法无法被重写

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值