Java基础:面向对象三特性(待更新)

1、封装 

字面意思,把东西装起来:隐藏、保护、提供方便使用的方式(例如快递打包、水管)。在这里指,将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问,把尽可能多的东西藏起来,对外提供便捷的接口。

用private关键字将属性隐藏,提供公共的访问接口getter/setter,如果有所限制,在setter中进行设置。

好处:让编程变得简单,找对象、调方法就行。

1.1 private关键字

private关键字,对属性进行私有化,被private修饰的成员只能在本类中访问。

访问修饰符:访问权限控制

◉ public:公共的,整个工程都可以访问 

◌ protected:受保护的(包级私有+子类),除了本包之外,继承该类的所有子类也可以访问

◌  默认的(无关键字):包级私有,本类所在的包内所有的文件都可以访问 

◉ private:私有的,本类内部才能访问

修饰符 \ 作用域同一个类中同一个包中子类中任何地方
private可以不可以不可以不可以
默认修饰符可以可以不可以不可以
protected可以可以可以不可以
public可以可以可以可以

 被private修饰的成员,用之前我们调用成员变量方式会报错

//定义一个学生类
public class Student{
    //private修饰的变量
    private String name;
    private int age;
    private String gender;
}

==================================

//测试类
public class Test{
    public static void main(String[] args){
        Student s=new Student();
        s.name="张三";//报错
    }
}

 

所以我们在使用private私有化后,要提供公共的访问接口:getter/setter。

1.2 getter/setter访问接口

getter和setter分别对应属性的出口和入口:

setter方法:给成员变量赋值

getter方法:对外提供成员变量的值

如果有特殊的条件限制,只能在setter中对赋值进行设定

getter是为了获取属性值,所以必然有return语句

//定义一个学生类
public class Student {

    //private修饰的变量
    private String name;
    private int age;
    private String gender;

    //权限修饰符用public 表示是公共的,在所有的地方都能调用这个方法
    //setter方法:接收数据,给成员变量赋值,有参,无返回值
    public void setName(String name) {//给name赋值
        this.name = name;
    }

    //getter方法:对外提供,无参,有返回值
    public String getName() {//对外提供name属性
        return name;
    }

    //对年龄有限制,在setter方法中进行条件判断
    public void setAge(int a) {
        if(a>=18 && a<=22){
            age = a;
        }else{
            System.out.println("年龄超出范围");
    }

    public int getAge() {
        return age;
    }

    public void setGender(String gender) {
        //当成员变量名和形参参名一样时,用this指向成员变量
        //成员变量成员方法都需要用对象名调用,这里的this就代替了对象名
        this.gender = gender;
    }

    public String getGender() {
        return gender;
    }
}

==================================

//测试类
public class Test {
    public static void main(String[] args){
        Student s1=new Student();
        s1.setName("张三");
        s1.setAge(16);
        System.out.println(s1.getName()+"的年龄是"+s1.getAge());

        Student s2=new Student();
        s2.setName("李四");
        s2.setAge(20);
        System.out.println(s2.getName()+"的年龄是"+s2.getAge());
    }
}

输出结果:

年龄超出范围
张三的年龄是0
李四的年龄是20

由于张三的年龄超出年龄范围,系统取默认值为0.


 getter和setter方法快速自动生成的 快捷键

Alt+insert

 如果有有参构造,有参构造中的赋值也应该调用setter,以便调用setter的限制

1.3 包

包,作为Java源代码的第一条语句,用package声明包,以分号结尾。

包名由小写字母组成,不能以圆点开头或结尾

package声明第一行(忽略注释)

其次是import

然后是

不要在src下直接写类,否则的话在别的包内是找不到这个类的

2、继承

2.1 extends关键字

子类共同的属性和方法,抽象出父类,子类用extends关键字基础父类的可见成员,java是单根继承,提高代码重用性,子类和父类满足is-a的关系

A extends B代表:A类继承了B类的成员属性成员方法(可见的)。

在继承过程中,会默认创建父类对象,子类对象继承该父类对象的全部成员 ,实现代码重用。

java中只允许单根继承,一个类只能继承一个直接父类。(要想继承别的就定义一个“爷爷”类)

Object类 是 所有类的父类。 

2.2 继承与构造方法

1)当父类不存在无参构造时,子类会编译报错,因此父类必须有无参构造

2)创建子类对象时,会先执行父类无参构造,再执行子类无参构造

public class Pet {//把Penguin和Dog公共的部分抽离出来做父类
    private String name;
    private int health;
    private int love;

    public Pet(String name, int health, int love) {
        this.name = name;
        this.health = health;
        this.love = love;
    }

    public Pet() {
        System.out.println("父类无参");
    }
}
==========================================================
public class Cat extends Pet{
    public Cat(){
        System.out.println("子类无参");
    }

==========================================================
public class TestPet {
    public static void main(String[] args) {
        Cat c=new Cat();
    }
}

运行结果:

父类无参
子类无参

 如果是创建有参对象 ,会先执行父类无参构造,再执行子类有参构造

public class Pet {//把Penguin和Dog公共的部分抽离出来做父类
    private String name;
    private int health;
    private int love;

    public Pet(String name, int health, int love) {
        this.name = name;
        this.health = health;
        this.love = love;
    }

    public Pet() {
        System.out.println("父类无参");
    }
}
==========================================================
public class Cat extends Pet{
    public Cat(){
        System.out.println("子类无参");
    }
    public Cat(int test){
        System.out.println("子类有参");
    }

==========================================================
public class TestPet {
    public static void main(String[] args) {
        Cat c=new Cat();
    }
}

运行结果:

父类无参
子类有参

如果在子类构造方法中用super(...)来指定父类有参,则不再调用父类无参

public class Pet {//把Penguin和Dog公共的部分抽离出来做父类
    private String name;
    private int health;
    private int love;

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

    public Pet() {
        System.out.println("父类无参");
    }
}
==========================================================
public class Cat extends Pet{
    public Cat(){
        System.out.println("子类无参");
    }
    public Cat(int test){
        super("aaa",1,1);
        System.out.println("子类有参");
    }

==========================================================
public class TestPet {
    public static void main(String[] args) {
        Cat c=new Cat();
    }
}

按住Ctrl鼠标悬浮在super关键字上方,可以看见super关键字 指向父类的 有参构造

 运行结果:

父类有参
子类有参

2.3 Object类

Object类 是 所有类的父类。

2.4 子类继承父类的...

非私有私有private
构造方法不能继承不能继承
成员变量能继承能继承,但不能直接使用
成员方法能继承不能继承
  • 继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里
  • 继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里

 子类与父类要符合 is-a 关系的设计

is-a,顾名思义,是一个,代表继承关系。 
如果A is-a B,那么B就是A的父类。 

3、多态

同类型的对象,表现的不同形态。即 同一个引用类型,使用不同的实例对象而产生不同的操作结果,一个类型的方法在其子类中有多种不同的表现形式

父类的方法被多个子类重写的前提下,父类作为形参,子类对象作为实参在方法中调用了父类的被重写方法,会自动调用传入实参的重写后的子类方法 

多态的前提:

  • 有继承/实现关系
  • 有父类引用指向子类对象
  • 有方法的重写

实现步骤:
1、父子继承关系,且多个子类重写了父类的某一个方法

2、父类的类型作为方法的形参类型,用形参调用父类的被重写的方法

3、在实际调用时,以子类对象作为传入的实参能根据传入的子类类型,自动调用该类中重写后的方法

好处:可扩展性强,维护性高,代码量较少,提高了重用性。但耦合性高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值