1.8:面向对象(中)

 前言:菜鸟一枚,如有问题欢迎大家在评论区指出,我们一起学习。

1.8.1:静态关键字(static)

        在类中声明的实例变量,其值是每一个对象独立的。但是有些成员变量的值不需要或不能每一个对象单独存储一份,即有些成员变量和当前类的对象无关。在类中声明的实例方法,在类的外面必须要先创建对象,才能调用。但是有些方法的调用和当前类的对象无关,那么创建对象就有点麻烦了。此时,就需要将和当前类的对象无关的成员变量、成员方法声明为静态的(static)。 

静态变量的特点:静态变量默认值和实例变量一样;静态变量的值是所有对象共用,属于类的,所以又叫做类变量;允许访问时,可以通过类名.变量名来进行访问,当然也可以使用对象名.变量名来进行访问(不推荐);不同于实例变量,任何一个对象修改静态变量,都会导致整个使用该变量的对象所使用的该变量值改变。

静态方法的特点:静态方法在其他类中可以通过“类名.静态方法“的方式调用。也可以通过”对象.静态方法“的方式调用(不推荐);静态方法可以被子类继承,但不能被子类重写

静态的注意事项:非静态可以直接访问静态,也可以访问非静态的,但是非静态只能访问非静态的。静态的方法和静态的代码块中,不允许出现this和super关键字,如果有重名问题,使用“类名.”进行区别。

代码示例:

public class Student {
    public String name;
    public int age;
    //static可以修饰属性,也可以修饰方法
    //静态属性叫类变量,静态属性全类用一个,任何一个对象对静态属性修改,都会影响到全部
    public static String school;

    public Student() {
    }

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

    public String getInfo() {
        return "name:" + name + ",age:" + age;
    }

    //静态方法也是可以直接用类调用
    //静态方法和普通方法唯一的区别是静态方法只 能访问静态成员(属性,方法),普通方法都可以访问
    public static void methodOne() {
        System.out.println("in methodOne");
        System.out.println(school);
//        System.out.println(name);

    }
}
public class TestStudent {
    public static void main(String[] args) {
        //static修饰的属性或者方法不需要对象,可以直接用类调用
        //静态属性随着类的加载已经在方法区分配内存
        Student.school = "清华";
        Student s1 = new Student();
        Student s2 = new Student();
        s1.name = "Tom";
        s2.name = "Jack";
        s1.age = 18;
        s2.age = 19;
        System.out.println(s1.getInfo());
        System.out.println(s2.getInfo());
    }
}

1.8.2:封装与私有关键字(private)

封装:随着我们系统越来越复杂,类会越来越多,那么类之间的访问边界必须把握好,面向对象的开发原则要遵循“高内聚、低耦合”,而“高内聚,低耦合”的体现之一:

高内聚:类的内部数据操作细节自己完成,不允许外部干涉;

低耦合:仅对外暴露少量的方法用于使用

         隐藏对象内部的复杂性,只对外公开简单和可控的访问方式,从而提高系统的可扩展性、可维护性。通俗的讲,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

实现封装就是指控制类或成员的可见性范围?这就需要依赖访问控制修饰符,也称为权限修饰符来控制。

外部类:public和缺省

成员变量、成员方法、构造器、成员内部类:public,protected,缺省,private  

        成员变量私有化后,其他类若想访问,有没有一种方法来进行访问了。答案是有,java提供了get/set方法来对私有变量进行操作。

示例代码:

public class Student {
    //私有属性本类使用
    private String stuName;
    private int stuAge;

    /*    public Student() {
        }

        public Student(String stuName, int stuAge) {
            this.stuName = stuName;
            this.stuAge = stuAge;
        }*/
    //使用set方法为私有属性赋值
    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    //使用get方法获取私有属性的值
    public String getStuName() {
        return stuName;
    }

    //使用私有属性并使用set方法的好处是:它可以对属性值进行设置,避免不正确的属性值
    public void setStuAge(int stuAge) {
        if (stuAge < 0) {
            this.stuAge = 0;
        } else {
            this.stuAge = stuAge;
        }
    }

    public int getStuAge() {
        return stuAge;
    }
public class TestStudent {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setStuName("Tom");
        s1.setStuAge(18);
        System.out.println(s1.getStuName()+s1.getStuAge());
    }
}

 1.8.3:继承

概念:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类中无需再定义这些属性和行为,只需要和抽取出来的类构成某种关系。 其中,多个类可以称为子类,也叫派生类;多个类抽取出来的这个类称为父类超类(superclass)或者基类。继承可以提高代码的扩展性和复用性。

使用extends关键字就可以实现一个子类继承另外一个父类。

示例代码:

public class Pet {
    private String name;
    private int age;
    private String type;

    public Pet() {
    }

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

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public String getInfo() {
        return "名字:" + name + ",年龄:" + age + ",品种:" + type;
    }

    public void play(){
        System.out.println("和主任玩耍");
    }
}
//Dog extends Pet   Dog类继承Pet类,Dog是子类,Pet是父类。
//子类可以继承父类所有的属性和方法,但是构造器不能继承

//java只支持单继承,不支持多重继承,即不能同时继承两个类
//java支持多层继承,即一个类可以继承一个子类
//一个父类可以同时拥有多个子类
//若一个类没有显示的父类,则它继承于Object类,即Object类是所有java类的总父类
public class Dog extends Pet {
    //可以在父类的基础上增加属性和方法
    private String color;

    public String getColor() {
        return color;
    }

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

    public void work(){
        System.out.println("工作");
    }
}

public class TestOne {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.setName("旺财");
        System.out.println("名字" + dog.getName());
        dog.play();
        dog.work();
        Cat cat = new Cat();
        cat.setName("汤姆");
        System.out.println("名字" + cat.getName());
        cat.play();
    }
}

子类虽不能继承父类的构造器, 但是子类可以调用父类的构造器

示例代码: 

public class Pet {
    private String name;
    private int age;

    public Pet() {
        System.out.println("父类无参");
    }

    public Pet(String name, int age) {
        System.out.println("父类有参");
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

public class Dog extends Pet{
    private String type;
    public Dog() {
        System.out.println("子类无参");
    }

//    public Dog(String name, int age) {
//        super(name, age);
//        System.out.println("子类有参");
//    }


    public Dog(String name, int age) {
        super(name, age);
        System.out.println("子类有参");
    }

    public Dog(String name, int age, String type) {
        super(name, age);
        this.type = type;
        System.out.println("子类增加有参");
    }

public class TestDog {
    public static void main(String[] args) {
        Pet pet1 = new Pet();
        System.out.println("父类无参构造结束---------");
        Pet pet = new Pet("小宝",12);
        System.out.println(pet.getName()+pet.getAge());
        System.out.println("父类有参创建结束-----------------------");
        Dog dog = new Dog();
        System.out.println("子类无参构造结束---------");
        Dog dog2 = new Dog("张飞",12);
        System.out.println(dog2.getName()+dog2.getAge());
        System.out.println("子类有参构造结束");
        Dog dog3 = new Dog("zhao",12,"bai");
        System.out.println(dog3.getName()+dog3.getAge()+dog3.getType());

    }
}

 

总结:一个类没有显式构造器时,java自动提供一个隐式无参的构造器。 子类继承父类时,子类如果没有显式的构造器,也会同样创建一个隐式无参的构造器。 子类这个隐式无参的构造器,会先调用父类隐式无参的构造器。 如果子类有一个显式有参的构造器,这个构造器的第一句代码必须为super(父类属性名1,父类属性名2), 子类若有父类没有的属性,后面则可使用 this.属性名 = 属性名 来初始化这个属性。

当子类从父类继承的方法无法体现子类的特征时,子类能否对这个方法进行修改以反应子类的特征?答案是可以,java提供了方法的重写。

1.8.4:方法的重写

子类认为从父类继承的方法无法体现子类的特征,方法重写
方法重写:必须发生在子类中,子类编写一个和父类方法方法名,参数列表一样的方法
一旦发生方法重写,子类对象再调用的是方法一定是子类重写后的方法
在子类类体里可以使用super关键字来调用父类重写前的方法。
父类方法的返回类型如果是基础数据类型和void时,子类返回类型一致;父类如果是引用数据类型,子类返回类型必须小于等于父类类型
父类如果抛出异常,子类必须抛出同样的异常或者抛出父类异常的子异常

示例代码:在上面代码Dog子类中重写父类Pet 中的play方法

    @Override
    //override检查是否为方法重写,可写可不写,建议写,方便阅读代码
    public void play(){
        super.play();
        System.out.println("玩飞盘");
    }
}

重写和重载是一样的吗?

并不是,首先重载后的方法和重载前的方法并不是同一个方法,但重写后的方法是同一个方法。重载发生在同一个类中,方法名一样,参数列表不一样,但是对返回类型无要求;重写发生在子类中,方法名和参数列表必须一样

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

oooosuperstar

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

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

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

打赏作者

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

抵扣说明:

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

余额充值