使用IDEA学JAVA第四天

今天是寒假学JAVA第三天,主要学习了this关键字、封装、继承、抽象类、接口、多态,内容较多,希望大家认真学习。

一、面向对象三大特征

1. this关键字(原理、理解)

  • 基本概念:在构造方法中和成员方法中访问成员变量时,编译器会加上this.的前缀,而this.相当于汉语中"我的",当不同的对象调用同一个方法时,由于调用方法的对象不同导致this关键字不同,从而this.方式访问的结果也就随之不同。
  • 使用方式 (1)当形参变量名与成员变量名相同时,在方法体中会优先使用形参变量(就近原则),若希望使用 成员变量,则需要在成员变量的前面加上this.的前缀,明确要求该变量是成员变量。
    (2)在构造方法的第一行可以使用this()的方式来调用本类中的其它构造方法(了解)。

2.封装

  • 基本概念通常情况下可以在测试类给成员变量赋值一些合法但不合理的数值,无论是编译阶段还是运行阶段都不会报错或者给出提示,此时与现实生活不符。为了避免上述错误的发生,就需要对成员变量进行密封包装处理,来隐藏成员变量的细节以及保证成员变量数值的合理性,该机制就叫做封装。
  • 实现流程 (1)私有化成员变量,使用private关键字修饰; (2)提供公有的get和set方法,并在方法体中进行合理值的判断; (3)在构造方法中调用set方法进行合理值的判断;
  • 实体类的封装: 在项目开发中,通常com.XXXX.bean;com.XXXX.domain;com.XXX.entity;com.XXX.pojo
    这些包当中通常情况下存放的都是实体类。
  • 实体类封装的步骤: 1、私有化成员变量; 2、提供公有的get/set方法 3、提供无参/有参/全参的构造方法 4、重写toString()、equals和hashCode()
  • 案例:编程实现Person类的封装,特征有:姓名、年龄,要求提供打印所有特征的方法。编程实现PersonTest类,在main方法中使用有参方式创建两个Person类型的对象并打印特征。
public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class PersonTest {
    public static void main(String[] args) {
        Person p1 = new Person("张三",18);
        Person p2 = new Person("李四",18);
        System.out.println(p1.toString());
        System.out.println(p2.toString());
    }
}

3.继承

  • 发生在父子之间父类(基类) 人类特征:姓名、年龄行为:吃饭、娱乐学生类特征:姓名、年龄、学号行为:吃饭、娱乐、学习 教师类特征:姓名、年龄、工号行为:吃饭、娱乐、讲课工人类特征:姓名、年龄、薪水行为:吃饭、娱乐、工作 学生类 吸收人类特征:学号行为;
    学习教师类吸收人类:特征:工号行为; 讲课工人类吸收人类:特征:薪水行为:工作.…
  • 公共类中已有特征和行为而在多个类型只需要编写自己独有特征和行为的机制,叫做继承。使用继承提高了代码的复用性,可维护性以及扩展性。在Java语言中使用extends(扩展)关键字来表示继承关系。
  • java只支持单继承,可以有多重继承,一个子类只能有一个父类,而一个父类可以有多个子类(简单来说就是一个孩子一个爹,一个爹可以有多个孩子)
  • 子类is a父类 如:public class Worker extends Person{}.表示Worker类继承自Person类 其中Person类叫做超类、父类、基类。其中Worker类叫做派生类、子类、孩子类。
  • 注意事项 (1)子类不能继承父类的构造方法和私有方法,但私有成员变量可以被继承只是不能直接访问。 (2)无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法,来初始化从父类
    中继承的成员变量,相当于在构造方法的第一行增加代码:super()的效果。
    super:通过super,可以访问父类构造方法(通过super的构造方法的代码,必须写在子类构造方法的第一行
    通过super,可以访问父类的属性;通过super,可以访问父类的方法 (3)使用继承必须满足逻辑关系:子类 is a
    父类,也就是不能滥用继承。 (4)Java语言中只支持单继承不支持多继承,也就是说一个子类只能有一个父类,但一个父类 可以有多个子类。

3.1.方法的重写(Override)

  • 方法的重写 (1)基本概念从父类中继承下来的方法不满足子类的需求时,就需要在子类中重新写一个和父类一样的方法来覆盖从父类中继承下来的版本,该方式就叫做方法的重写,
    (2)重写的原则 a.要求方法名相同、参数列表相同以及返回值类型相同,从jdk1.5开始允许返回子类类型。
    b.要求方法的访问权限不能变小,可以相同或者变大。 c.要求方法不能抛出更大的异常(异常机制。
    d.声明为static和private的方法不能被重写,但是能够被再次声明。
  • 面试题:重写(Override)和重载(Overload)的区别 1、发生的位置 重载:一个类中 重写:子父类中 2、参数列表限制 重载:必须不同 重写:必须相同
    3.返回值类型 重载:与返回值类型无关 重写:返回值类型必须一致
    4.访问权限: 重载:与访问权限无关 重写:重写后(子)的方法的访问权限不能小于被重写(父)方法的权限
    5.异常处理: 重载:跟异常没有关系 重写:异常范围可以小,但是不能抛出新的异常
  • 练习:编程实现Animal类的封装,特征有:名字和毛色,要求提供打印所有特征的方法。编程实现Dog类的封装并继承自Animal类,该类的特征有:牙齿数量,要求提供打印所有特征的方法
    编程实现DogTest类,在main方法中分别使用无参和有参方式构造Dog类型对象并打印特征。
public class Animal {
    private String name;
    private String color;

    public Animal() {
    }

    public Animal(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public void show() {
        System.out.println("我的名字叫做:" + getName() + ",毛色是" + getColor() + "色。" );
    }

}

public class Dog extends Animal{
    private int teechNumber;

    public Dog() {
    }

    public Dog(String name, String color, int teechNumber) {
        super(name, color);
        this.teechNumber = teechNumber;
    }

    public int getTeechNumber() {
        return teechNumber;
    }

    public void setTeechNumber(int teechNumber) {
        this.teechNumber = teechNumber;
    }

    @Override
    public void show() {
        System.out.println("我的名字叫做:" + getName() + ",毛色是" + getColor() + "色," + "牙齿数量为:" + getTeechNumber());

    }
}

public class DogTest {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.show();
        Dog dog1 = new Dog("小黑","黑色",30);
        dog1.show();
    }
}

3.2 访问控制符

a.public修饰的成员可以在任意位置使用;
b.private修饰的成员只能在本类内部使用;
c.通常情况下,成员方法都使用public关键字修饰,成员变量都使用private关键字修饰;

3.3 包的声明

package包名:表示声明单层包
package包名1.包名2.包名3.包名n:表示多层包,为了便于管理以及解决命名冲突的问题;

3.4 final关键字

final关键字: final关键字用于修饰属性、变量(表示变量变为了常量,无法再对其再次进行赋值)
final修饰的局部变量,只能赋值一次(可以先声明后赋值) final修饰的成员变量时,必须在声明时赋值。 final关键字用于修饰类
final修饰类,不可以被继承 final关键字用于修饰方法 final修饰方法,不允许被子类重写 全局常量(public static
final) 全局常量的命名规范: 由一个或多个单词组成,单词与单词之间必须使用下划线隔开,单词中所有字母大写。

4.抽象类

4.1 概念

抽象类必须使用abstract class声明 一个抽象类中可以没有抽象方法。抽象方法必须写在抽象类或者接口中。 格式: abstract
class 类名{ 抽象类}

4.2 抽象方法

只声明而未实现的方法称为抽象方法(未实现指的是:没有"()"方法体),抽象方法必须使用abstract关键字声明。 格式: abstract
class 类名(//抽象类 public abstract void 方法名();//抽象方法,只声明而未实现 }

4.3 不能被实例化

在抽象类的使用中有几个原则: 抽象类本身是不能直接进行实例化操作的,即:不能直接使用关键字new完成。
一个抽象类必须被子类所继承,被继承的子类(如果不是抽象类)则必须覆写(重写)抽象类中的全部抽象方法。

4.4 抽象类和普通类的区别

1、抽象类必须用public或protected修饰(如果为private修饰,那么子类则无法继承,也就无法实现其抽象方法)。默认缺省为
public
2、抽象类不可以使用new关键字创建对象,但是在子类创建对象时,抽象父类也会被JVM实例化。
如一个子类继承抽象类,那么必须实现其所有的抽象方法。如果有未实现的抽象方法,那么子类也必须定义为abstract类。

5.接口

5.1 概念

如果一个类中的全部方法都是抽象方法,全部属性都是全局常量,那么此时就可以将这个类定义成一个接口。 定义格式: interface
接口名称{ 全局常量: 抽象方法; }

5.2 面向接口编程思想

这种思想是接口是定义(规范,约束)与实现(名实分离的原则)的分离。 优点: 降低程序的耦合性,易于程序的扩展 ,有利于程序的维护。

5.3 全局常量和抽象方法的简写

因为接口本身都是由全局常量和抽象方法组成,所以接口中的成员定义可以简写: 1、全局常量编写时,可以省略public static final
关键字,例如: public static final String INFO= “円”; 简写后: String INFO = “内容”:
2、抽象方法编写时,可以省略 public abstract 关键字, 例如: public abstract void print() ;
简写后: void print();

5.4 接口的实现implements

接口可以多实现: 格式: class 子类 implements父接口1,父接口2…{ }
以上的代码称为接口的实现。那么如果一个类即要实现接口,又要继承抽象类的话,则按照以下的格式编写即可: class 子类 extends 父类
implements 父接口1,父接口2…{ }

5.5 接口的继承

接口因为都是抽象部分,不存在具体的实现,所以允许多继承,例如: interface C extends A,B{} 注意:
如果一个接口要想使用,必须依靠子类。子类(如果不是抽象类的话)要实现接口中的所有抽象方法。

  • 面试题:接口和抽象类的区别
    1、抽象类要被子类继承,接口要被类实现。
    2、接口只能声明抽象方法,抽象类中可以声明抽象方法,也可以写非抽象方法。
    3、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
    4、抽象类使用继承来使用,无法多继承。接口使用实现来使用,可以多实现
    5、抽象类中可以包含static方法,但是接口中不允许(静态方法不能被子类重写,因此接口中不能声明静态方法)
    6、接口不能有构造方法,但是抽象类可以有

6.多态

6.1 基本概念

多态主要指同一种事物表现出来的多种形态。 饮料:可乐、雪碧、乐虎、加多宝、红牛、脉动… 宠物:猫、狗、鸟、小强、鱼…
人:学生、教师、工人、保安… 语法格式:父类类型引用变量名=new子类类型();//父类型的引用指向子类型的对象 (子类向上转型为父类)
如:Person p =new Worker(); Shape shape=new Rect(); pw.show();

6.2 多态的效果

(1)当父类类型的引用指向子类类型的对象时,父类类型的引用可以直接调用父类独有的方法;
(2)当父类类型的引用指向子类类型的对象时,父类类型的引用不可以直接调用子类独有的方法;
(3)对于父子类都有的非静态方法来说,编译阶段调用父类版本,运行阶段调用子类重写的版本;
(4)对于父子类都有的静态方法来说,编译和运行阶段都调用父类版本;

6.3 引用数据类型之间的转换

(1)引用数据类型之间的转换方式有两种:自动类型转换和强制类型转换。其中自动类型转换主要指小类型向大类型的转换,也就是子类转换为父类。其中强制类型转换主要指大类型向小类型的转换,也就是父类转换为子类。
(2)引用数据类型之间的转换必须发生在父子类之间,否则编译报错。(3)若强转的目标类型并不是该引用真正指向的数据类型时,则编译通过,运行阶段发生类型转换异常。
(4)为了避免上述错误的发生,应该在强转之前进行判断,格式如下: if(引用变量instanceof
数据类型)//判断引用变量指向的对象是否为后面的数据类型

6.4 实际意义

多态的实际意义在于屏蔽不同子类的差异性实现通用的编程带来不同的效果。

总结

今天整理了满满的干货,希望大家能喜欢,我会继续加油的!

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微笑向阳~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值