JAVA初学者第八天

本文详细讲解了Java中的`this`与`super`关键字的区别,包括访问变量和方法、调用构造器以及表示的对象的不同。此外,介绍了抽象类的概念、定义方式、使用场景及注意事项,并通过程序员、项目经理、前台小姐姐的案例展示了抽象类的实践。还涵盖了多态的概念、实现条件、代码实现以及多态转型的相关内容。最后提到了权限修饰词`final`的作用以及多态转型中的注意事项。
摘要由CSDN通过智能技术生成

this关键字和super的区别

① 访问变量(方法)时不同

        this.变量/方法:当前类的属性、方法

        super.变量/方法:当前类父类的属性、方法

② 调用构造方法时:

        this():调用本类的空参构造

        super():调用父类的无参构造this()和super() 不能共存:this()需要写在构造方法的第一行,super()也要写在构造方法的第一行;

③ 表示的对象时不同

        this:当前类的对象,或者是谁调用该方法,this就表示谁

        super:当前类父类的对象,或者谁调用该方法,super就是调用者的父类对象

 继承实际应用---抽象类

抽象类

当一个类中,出现只有对方法的声明、没有方法的具体实现,这样的方法被称为抽象方法,一旦类中出现了抽象方法,那么这个类就称为抽象类;

抽象类中不一定有抽象方法,抽象类中也可以存在普通方法;

 抽象方法的定义方式

将以前定义普通方法时的大括号给省略的(方法没有方法体),并且使用关键字 abstract 对方法进行修饰格式:

        权限修饰词 abstract 返回值类型 方法名(参数列表);

        public abstract void getArea();

 抽象类的定义

跟以前声明类的方式一样,只不过需要的权限修饰词后面加上 abstract

格式:

public abstract class 类名{

}

抽象类的使用场景

 当使用继承的思想进行程序设计时,需要先进行共性的抽取,此时就有可能会有行为的抽取,在抽取行为时,因为每一个子类他的行为可能是不一样的,所以在超类中无法描述行为的具体实现过程;遇到这种时候我们就可以只抽取行为,不去实现行为的过程,将行为定义成抽象方法,将类定义为抽象类。

 案例:程序员、项目经理、前台小姐姐练习修改

public abstract class Employee {
 String name;
 String id;
 int age;
 double work_age;
 double salary;
 String department;
 public abstract void work();
}
public class Programmer extends Employee {
 double money;
 public void work() {
 System.out.println("撸代码");
 }
}
public class Manager extends Employee{
 double money;
 public void work(){
 System.out.println("瞎转悠");
 }
}
public class Young_Sister extends Employee{
 public void work() {
 System.out.println("接待客户");
 }
}

抽象类使用注意事项

① 抽象类可以被普通继承,也可以被抽象类继承

普通继承抽象类:系统会强制要求重写抽象类中的抽象方法

抽象类继承抽象类:可以不用重写父类的抽象方法(抽象类不能使用传统的方式创建对象)

抽象类不能使用 类名 对象名 = new 类名();这种方式创建对象

② 如果抽象类被抽象类继承,想要创建子类对象

a. 再创建一个普通类来继承抽象类,创建子类的对象来访问抽象类中的方法

b. 使用匿名内部类或者兰姆达表达式来快速创建抽象类的对象

③ 抽象类中可以定义变量,也拥有构造方法,但是不能直接使用抽象类的构造方法来实例化对象;

在一个类中,判断其有没有构造方法的方式是看在这个类中是否可以定义变量(构造方法就是用来给变量进行初始化赋值的,有变量就证明需要初始化赋值,所以就需要有构造方法)

 继承总结

① java中只允许单继承或者多层继承,不允许多继承

单继承:一个孩子只能有一个亲爹,一个子类同一时间只能存在一个父类

多层继承:a extends b extends c extends d,a可以是b的子类,b可以是c的子类,c可以是d的子类

多继承:a extends b,c,java中不允许这样做;因为多个父类中可能存在相同的方法,如果同时继承子类就没办法 区分到底使用哪个父类中的方法

② 继承的过程中,构造方法不能被继承

③ 继承中进行成员方法的访问时:

a. 如果子类和父类中都定义了不同的方法,那在进行访问时,父类只能访问父类中定义的方法,子类可以访问父类和子类中定义的方法

b. 如果父类中的方法和子类的方法相同(方法的重写),那么在访问时,子类对象访问的结果是子类重写后的结果

 代码块 ---- 属性或者是局部变量的赋值

① 局部代码块(局部/成员变量)

a. 在方法中定义

b. 格式:{}

案例:

public class Programmer extends Employee {

double money;

public void work() {

}

int i = 100;

money = 1000;

}

System.out.println("撸代码,挣了"+money);

}

}

c. 使用局部代码块的好处:

1. 限定变量的生命周期,一旦代码块执行结束,其中定义的变量就会被系统回收

2. 在代码块内进行的成员变量的赋值,在代码块结束之后仍然存在

② 构造代码块(属性)

a. 定义在类中方法外

b. 定义的格式:{}

c. 案例

public class Programmer extends Employee {

double money;

{

money = 1000;

}

public void work() {

System.out.println("撸代码,挣了"+money);

}

}

d. 构造代码块会比构造方法先执行

e. 构造代码块的使用:

1. 无需编程人员调用,由JVM自动调用

2. 每一个创建对象都会先执行构造代码块的内容

3. 编程时,如果有的数据需要在创建对象之前就有,就在构造代码块中进行赋值

③ 静态代码块(静态的属性,会比main方法还要先执行)

a. 类中方法外

b. 格式:static { }

c. 案例:

public class Image_Utils {

public static BufferedImage image = null;

static {

try {

image = ImageIO.read(Image_Utils.class.getResource(""));

}

catch (IOException e) {

e.printStackTrace();

}

}

}

 内部类 ---- 更好的进行代码的封装、快速创建对象

① 分类

a. 局部内部类(定义在方法中)

格式:

class 内部类类名{

属性;方法;

}

b. 成员内部类(类中方法外)

格式:

class 内部类类名{

属性;方法;

}

c. 匿名内部类

功能:快速的创建抽象类或者接口的对象(要有继承或者实现的关系)

格式:

new 抽象类、接口(){

需要去实现抽象类或者接口中所有的抽象方法(方法的重写)

}.属性(方法)

 匿名内部类的应用

① 当一个抽象类或者是接口需要创建对象时

② 当接口或者是抽象类的对象作为方法的参数时(常遇)

public abstract class Animal {
 public abstract void sayHello();
}
 public class Test_Animal {
 public static void sayHello(Animal a){
 a.sayHello();
 }
 public static void main(String[] args) {
 sayHello(new Animal() {
 public void sayHello() {
 System.out.println("旺旺旺");
 }
 });
 }
}

 权限修饰词 ---- 设置方法或者是属性以及类的访问权限

 final关键字

修饰内容作用
变量将变量变成常量
方法表示该方法时一个终态的方法,不能被重写,可以被继承
表示这个类是一个终态类,该类不能被继承

多态

多态的概念

事物的多种形态,不同形态的时候所具备的功能不一样

对象的多态:同一个对象在不同的环境中具有不同的形态,功能也不同

行为的多态:可以是相同的也可以是不同对象,但是他们都具有相同的行为,行为所产生的效果也可以不同

 实现多态的前提

① 必须要有继承(类或者抽象类)或者是实现(接口)的关系

② 必须存在方法的重写

③ 需要有父类引用子类的对象(去调用方法)

 多态的代码实现

/// 超类,可以是普通类,抽象类,接口
public class Animal {
 int age;
 String name;
 public void eat(){
 System.out.println("这是animal的eat方法");
 }
}
// 一般是一个普通类,让 animal 和 dog 产生继承关系
public class Dog extends Animal{
 // 子类重写父类的方法
 public void eat(){
 System.out.println("这是dog的eat方法");
 }
}
// 测试类
public class Test01 {
 public static void main(String[] args) {
 // 父类引用子类的对象
 Animal animal = new Dog();
 animal.eat();
 }
}

使用父类引用子类对象时访问成员

① 成员变量:编译运行看左边

无论是编译还是运行都是以父类中的成员为准

② 成员方法:编译看左边,运行看右边:

编译期间查看父类中是否有方法的定义,如果有,编译成功,最终的执行结果却是以子类中重写后的方法为准;

如果父类中没有定义此方法,编译失败,程序报错

 多态转型

向上造型 - 自动完成

 父类引用子类对象

父类 父类对象名 = new 子类();

 向下转型(强制类型转换)

一定先有向上造型、再向下转型

父类 父类对象名 = new 子类();

子类 对象名 = (子类)父类对象名;

 向下转型的注意事项

① 如果,一个父类有多个子类,那么在向下转型之前最好先做一下类型的判断,如果类型匹配在进行转型,否则容易出现异常(类型转换异常 - ClassCastException)

② 在转型之前使用 instanceof 运算符进行类型的判断object instanceof 类

如果 object 属于类,结果就为true,

否则结果为false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值