Java初学日记 六 (面向对象3)

面向对象三

抽象类

特点

        抽象类不能创建对象,其他功能与正常类相同,可以有成员变量、成员方法、构造方法;

        主要就是在上层定义功能,让子类继承;

        一个子类一旦继承抽象类,要么重写所有抽象方法,要么该类也定义为抽象类;

         抽象类只能作为父类;

抽象方法

        抽象方法是一种特殊的方法,它只有声明,没有具体的实现;

        抽象方法必须用abstract关键字修饰;

为什么有

        在一些体系结构的顶端类中,有些功能没有必要实现,因为子类中所需的功能都不同,这是就可以使用抽象方法;

//方法重写
public class Dog extends Animal{
    public  void eat(){
        System.out.println("吃骨头");
    }
}
​
//定义抽象类
public abstract class Cat extends Animal{
​
}
/*
抽象类:
    使用abstract修饰的类是抽象类
    如果以一个类有抽象方法,则其必是抽象类
    一个抽象类不一定有抽象方法
 */
​
public abstract class Animal {
    private String name;
    private int age;
​
    public Animal(){
​
    }
​
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
/*
    抽象方法,没有代码块,使用abstract修饰
    只是定义了eat方法,没有具体实现
     */
​
    public abstract void eat();
}
public class Animal_Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
    }
}

面向对象语言的三大特征(前两个)

封装

        一般意义-->将重复出现的代码抽取成一个函数,成为代码的封装(包装);

        面向对象中实际意义-->(通过访问权限修饰符)将类的某些信息隐藏的类内部,不让外部直接访问操作,而用改类提供的方法来进行访问操作;

优点

        方便修改实现;

         隐藏类的信息;

        方便加入控制语句;

        在其他类需通过特定方法访问;

案例1:

        将类中成员变量私有化

public class packaging_test {
    private String name;
    private int age;
​
    //外部通过构造方法来访问成员变量
    //不实用,不灵活
    //不建议使用
//    public packaging_test(){
//        if (name.length() > 2 && name.length() < 6){
//            this.name = name;
//        }
//        if (age>=0&&age<150){
//            this.age = age;
//        }
//    }
    
    //向外提供一个公共的方法访问,可在此方法加入限制语句
    public void setName(String name){
        if (name.length() > 2 && name.length() < 6){
            this.name = name;
        }
    }
​
    public String getName(){
        return this.name;
    }
​
    public void setAge(int age){
        if (age>=0&&age<150){
            this.age = age;
        }
    }
​
    public int getAge(){
        return this.age;
    }
}
public class person_test {
    public static void main(String[] args) {
        packaging_test person = new packaging_test();
        //如果类中属性权限开放,其他类直接访问操作,则无法控制赋值
        //person.name = "@#$";
​
        //设置权限
        //person.name;报错
​
        //通过类方法进行访问
        person.setName("ctvybh");
        System.out.println(person.getName());
        person.setAge(25);
        System.out.println(person.getAge());
    }
}
案例2:

        将类中成员方法私有化

public class packaging_method {
    static packaging_method window = new packaging_method();
​
    //将构造方法私有化,让外界无法调用
    private packaging_method(){
    }
​
    public static packaging_method getWindow(){
        return window;
    }
}
public class window {
    public static void main(String[] args) {
        System.out.println(packaging_method.getWindow());
    }
}

继承

        多个类中存在相同的属性和行为时,将这些内容抽取到单独一个类(父类),则其余类(子类)无需在定义,当需要使用时,只需要与抽取出来的类构成继承关系即可;

优点

        减少了代码冗余,实现了代码的复用性;

        增强了程序的扩展性,子类可在自身中扩展自己特有的功能,而不影响其他类;

        类与类之间产生了“is-a”(什么是什么)的关系,为多态的使用提供了前提

时机

        当类与类符合”is-a“关系时;

语法

        通过extends关键字,可以声明一个类B继承类A所有的全部属性和行为,其意义是表示子类是对父类的扩展 ;

特点

        子类会继承父类所有的实例变量和实例方法 ;

        子类不能直接访问父类中私有的的成员变量和方法 ;

        Java支持多层继承(继承体系),展示继承的传递性 ;

        一个父类可以同时拥有多个子类 ;

        Java只支持单继承,不支持多重继承;

//当一个类没有显示继承,那么这个类默认继承Object类;
//类java.lang.Object是Java体系中最大的类,是类层次结构的根类,是其他所有类的父类,在其上没有其余的类,每个类都使用Object作为超类;
[修饰符] class 类A (extends Obiect){
    ...
}
​
//一个类只能直接继承一个类(间接可继承多个),继承的传递性;
[修饰符] class 类B extends 类A {
    ...
}

例:猫和狗都是动物-->抽取一个动物类-->让猫和狗继承动物类;

//狗类
public class Dog extends Animal{
    public void lookHome() {
        System.out.println("看家");
    }
}
//猫类
public class Cat extends Animal{
    public void catchMouse(){
        System.out.println("抓老鼠");
    }
}
//哮天犬-->进行间接继承,以展示继承的传递性;
public class Xiao_Tian_Quan extends Dog{
    public void fly(){
        System.out.println("飞");
    }
}
//动物类
public class Animal {
    private String name;
    private int 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;
    }
​
    public void eat(){
        System.out.println("吃东西");
    }
}
//测试类
public class Animal_test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setName("🔪哥");
        dog.setAge(3);
        System.out.print(dog.getAge() + "岁的");
        System.out.print(dog.getName());
        dog.lookHome();
​
        Cat cat = new Cat();
        cat.setName("喵桑");
        cat.setAge(4);
        System.out.print(cat.getAge() + "岁的");
        System.out.print(cat.getName());
        cat.catchMouse();
​
        Xiao_Tian_Quan XTQ = new Xiao_Tian_Quan();
        XTQ.setName("哮天犬");
        XTQ.setAge(1500);
        System.out.print(XTQ.getAge() + "岁的");
        System.out.print(XTQ.getName());
        XTQ.fly();
    }
}
方法的重写(Override)

        当父类中方法的实现无法满足子类的需求时,此时可以在子类中对父类的方法进行重写(也称覆盖),再此调用时会使用子类重写后的方法;

要求

        子类中重写方法的结构必须要与父类中方法的结构一致;

        方法名、参数列表、 返回值必须一致;

        重写的方法访问权限也应等于或大于父类方法权限;

        子类方法抛出的异常不能大于父类被重写方法的异常;

        在子类中进行方法的重写时,将“@Override”标识符定义在重写的方法上面-->用来检测格式是否符合要求,在阅读代码时明确知道此方法重写的;(也可不添加,只要保证重写的方法结构与父类方法结构一致即可)

注意

        构造方法、静态方法不能重写;

        成员变量不存在重写;

        父类私有方法不能重写;

          跨包的父类默认权限方法也不能重写;

//子类
public class Dog extends Animal{
    public void lookHome() {
        System.out.println("看家");
    }
    @Override
    public void eat(){
        System.out.println("吃骨头");
    }
}
​
//父类
public class Animal {
    private String name;
    private int 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;
    }
​
    public void eat(){
        System.out.println("吃东西");
    }
}
​
//测试类
public class Animal_test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setName("🔪哥");
        dog.setAge(3);
        System.out.print(dog.getAge() + "岁的");
        System.out.print(dog.getName());
        dog.eat();
     }
}
super
作用

        在Java类中使用super来调用父类中的指定操作;

        super可用于访问父类中定义的属性 ;

        super可用于调用父类中定义的成员方法 ;

        super可用于在子类构造方法中调用父类的构造方法;

注意

        super和this用法相似,注意区分-->super代表父类的内存标识,this表示本类对象的引用;

        不要把super误认为父类对象,在创建子类对象时,父类不会创建对象,只会将父类中的信息载入值子类对象中;

//狗类
public class Dog extends Animal{
    public void lookHome() {
        super.eat();
        System.out.println("看家");
    }
    @Override
    public void eat(){
        System.out.println("吃骨头");
    }
}
​
//动物类
public class Animal {
    private String name;
    private int 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;
    }
​
    public void eat(){
        System.out.println("吃东西");
    }
}
//测试类
public class Animal_test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setName("🔪哥");
        dog.setAge(3);
        dog.lookHome();
    }
 }
继承中的构造方法

        在创建子类对象时,必须先在子类构造方法的第一行调用父类的构造方法;(规定super(形参列表),必须声明在构造器的首行)

        子类继承父类时,不会继承父类的构造方法。只能通过“super(形参列表)” 的方式调用父类指定的构造方法;

        如果在子类构造器的首行没有显示调用super(形参列表),则子类此构造器 默认调用super(),即调用父类中空参的构造器;

        这么做是为了保证先对父类成员进行初始化;

public class Dog extends Animal{
    public Dog(){
        super();
        System.out.println("Dog的构造方法");
    }
    //有参构造
    public Dog(String name,int age){
        super(name,age);
    }
}
public class Animal {
    private String name;
    private int age;
​
    public Animal(){
        System.out.println("Animal的构造方法");
    }
​
    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;
    }
​
    public void eat(){
        System.out.println("吃东西");
    }
}
public class Animal_test {
    public static void main(String[] args) {
        Dog dog = new Dog("🔪哥",3);
    }
}
 

成员变量和局部变量

数据类型

        基本类型变量:byte、short、int、long、float、double、char、boolean(八种关键字);

        引用类型变量:类、数组、持有的是对象的地址;

成员变量

        位置分类:类中定义-->成员变量;

        权限:可使用权限修饰符;

        初始化:在构造方法中系统自动赋初值;

        生命周期:随着对象的创建而存在,对象销毁而销毁(非静态);

        随着类加载而存在,类销毁而销毁(静态);

        内存位置:在堆内存(非静态);方法区(静态);

局部变量

        方法中定义-->局部变量;

        权限:不可使用权限修饰符;

        初始化:必须手动赋初值;

        生命周期: 随着方法的调用而存在,方法结束销毁;

        内存位置:在栈内存;

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值