Java学习【Day 4】
程序员文章站
2022-03-08 11:57:29
...
文章目录
this()
通过当前的构造方法去调用本类的另一个构造方法。可以做到代码复用。
this(实际参数列表);
且这样的写法只能作为构造方法的第一个语句
public class Test_this {
public int year;
public int month;
public int day;
//无参构造方法
public Test_this(){
this(2021,5,27); //调用了有参构造方法
}
//有参构造方法
public Test_this(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
}
继承
有了继承关系,才有了方法的覆盖和多态机制
语法:
class 类名 extends 父类名{
类体;
}
继承的特性:
- B类继承A类。称A类是超类(superclass)、父类、基类;称B类是子类(subclass)、派生类、扩展类
- java只支持单继承,不能多继承。
- 虽然java不支持多继承,但能产生间接继承的效果
- 子类继承父类,除构造方法不能继承之外,剩下的都可以继承。父类中private修饰的属性不能在子类中直接访问,但可以间接通过别的方法访问。
- java中的类如果显示没有继承任何类,则默认继承Object类。Object是所有类的父类。继承结构中最顶点的是:Object
- 继承也有缺点,会导致两个类的耦合度高,父类的改变会影响的子类。
继承的例子:
package Demo;
public class Test_extends {
public static void main(String[] args){
CreditAccount cust1 = new CreditAccount();
cust1.setBalance(6.66); //使用父类的方法
System.out.println(cust1.getBalance());
}
}
//银行账户
//账号、余额
class Account {
private String autno;
private double balance;
public Account(){
}
public Account(String autno,double balance){
this.autno = autno;
this.balance = balance;
}
public void setBalance(double balance){
this.balance = balance;
}
public double getBalance(){
return this.balance;
}
}
//信用卡账户
//账号、余额、信誉度
class CreditAccount extends Account{
private double credit; //信誉度属性
public CreditAccount(){
}
public void dosome(){
System.out.println(getBalance());
}
public void setCredit(double credit){
this.credit = credit;
}
}
方法覆盖
又名方法重写。子类继承父类的方法,并对其进行重写。
覆盖的条件:
- 两个类必须要有继承关系
- 重写之后的方法和之前的方法具有:相同的返回值类型、相同的方法名、相同的形参。
- 访问权限不能更低,可以更高(比如高权限public不能被重写成低权限的privated、protected)
- 重写之后的方法不能比之前的方法抛出更多的异常,可以更少
方法覆盖的注意事项:
- 方法覆盖针对方法,和属性无关
- 私有方法不能被覆盖
- 构造方法不能被覆盖,因为构造方法不能被继承
- 方法覆盖只只针对“实例方法”,“静态方法的覆盖”没有意义
package Demo;
public class Test_Override {
public static void main(String[] args){
Chinese p1 = new Chinese();
p1.setName("小宏");
p1.speak();
English p2 = new English();
p2.setName("DMIND");
p2.speak();
}
}
class People{
private String name;
//构造方法
public People(){};
public People(String name){
this.name = name;
}
//setName和getName
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void speak(){
System.out.println(this.getName()+" ....");
}
}
class Chinese extends People{
public void speak(){
System.out.println(this.getName()+"说汉语");
}
}
class English extends People{
public void speak(){
System.out.println(this.getName()+"说嘤语");
}
}
多态
多种状态,多种形态。编译和运行有两个不同的状态
编译期叫做静态绑定
运行期叫做动态绑定
Animal a = new Cat();
编译的时候编译器发现a的类型是Animal,所以编译器会去Animal类中找move方法,找到了就绑定,编译通过。
但运行的时候和底层堆内存当中的实际对象有关
真正执行的时候会自动调用 “ 堆内存中真实对象 ”的相关方法
向上转型:子------>父(upcasting)
又被称为自动类型转换。 Animal a = new Cat();
向下转型:父------>子(downcasting)
又被称为强制类型转换。Cat c = (Cat) a;
需要添加强制类型转换符。
不管时向上转型还是向下转型,首先他们之间要有继承关系,这样编译器就不会报错
什么时候要向下转型?
需要调用或者执行子类对象中特有的方法时。必须进行向下转型才能调用。
向下转型的风险?
容易出现 ClassCastException(类型转换异常)
如何避免这个风险?
使用 instanceof运算符,可以在程序执行阶段动态的判断某个引用指向的对象。养成好习惯:在向下转型之前一定要使用 instanceof 运算符进行判断。
instanceof
可以在运行阶段动态判断引用指向的对象的类型。返回Boolean值
引用 instanceof 类型
a1 instanceof Cat
关于多态与instanceof的例子:
package Demo;
public class Test_duotai {
public static void main(String[] args){
Animal a2 = new Bird(); //向上转型
Animal a1 = new Cat(); //向上转型
a1.move();
//a1.Catchmouse(); //这句会报错的,因为无法通过编译阶段,编译时认为a1是Animal类所以找不到Carchmouse()而报错
Cat x = (Cat)a1; //想要调用Cat类特有的方法就得:向下转型。使用了强制转换符。
x.Catchmouse(); //成功调用特有方法
//向下转型前,使用instanceof进行判断,避免出现:ClassCastException(类型转换异常)
if(a2 instanceof Bird){
Bird y = (Bird)a2;
y.Sing();
}
else if (a2 instanceof Cat){
Cat y = (Cat)a2;
y.Catchmouse();
}
}
}
class Animal{
public void move(){
System.out.println("动物移动");
}
}
class Cat extends Animal{
public void move(){
System.out.println("猫移动");
}
//抓老鼠
public void Catchmouse(){
System.out.println("猫抓老鼠");
}
}
class Bird extends Animal{
public void move(){
System.out.println("鸟移动");
}
//歌鸣
public void Sing(){
System.out.println("鸟在歌鸣");
}
}
静态方法 “不存在” 覆盖
一般情况下,我们说静态方法 “不存在” 覆盖。静态方法的执行不需要对象
静态方法虽然可以使用引用.
的方式来调用,但是和对象没有关系,最后还是执行Animal.dosome()
package Demo;
public class Test_duotai {
public static void main(String[] args){
Animal a1 = new Cat(); //向上转型
a1.dosome();
}
class Animal{
public static void dosome(){
System.out.println("Aniaml的静态方法执行了");
}
}
class Cat extends Animal{
public static void dosome(){
System.out.println("Cat的静态方法执行了");
}
}
//Aniaml的静态方法执行了
下一篇: 项目中要用到的小实例2