【JavaSE】类和对象(上)

代码体现

//定义类的格式
public class 类名 {
    //可编写属性
    数据类型 变量名1;
    数据类型 变量名2;

    //可编写方法
    修饰符 返回值类型 方法名(参数) {
        执行语句;
    }
}

类的真正意义就是在描述事物。属性和功能统称为事物中的成员。

事物的成员分为两种:成员属性和成员功能。

成员属性===>成员变量(类中方法外)。

成员功能===>成员方法。

//创建对象的一般格式
类名 引用变量名 = new 类型();

成员变量使用:
    赋值格式:引用变量名.成员变量名 = 值;
    取值格式:引用变量名.成员变量名

成员方法使用格式:
    引用变量名.方法名(值1,值2,...);

局部变量和成员变量

区别一:定义的位置不同

定义在类中的方法外的变量是成员变量

定义在方法中或者方法的{}内语句里面的变量是局部变量

区别二:在内存中的位置不同

成员变量存储在堆中

局部变量存储在栈中

区别三:生命周期不同(皮之不存毛将焉附)

成员变量随着对象的出现而出现在堆中,随着对象的消失而从堆中消失

(成员变量和对象同生共死)

局部变量随着方法的运行而出现在栈中,随着方法的弹栈而消失

(局部变量和方法同生共死)

区别四:有没有默认值

成员变量因为在堆内存中,所有默认的初始化值,默认值和数组的默认值类似

局部变量没有默认的初始化值,必须手动的给其赋值才可以使用。


关键字private

private关键字,也是一个修饰符。可以将属性或者行为私有起来,无法访问。对外提供可访问的方法,让其他程序访问这些方法。同时在方法中可以对数据进行验证。

一般对成员属性的访问动作:赋值(设置set),取值(获取get),因此对私有的变量访问的方式可以提供对应的setXxxx或者getXxxx的方法。

/*
* 人类:
*    属性:姓名,年龄
*    行为:吃饭
*
* 使用关键字private:私有
* 当私有化变量后,变量不能在类外直接访问
* 如果用private修饰成员方法,这个成员方法不能在类外使用
*/

public class Person {
    //属性===》成员变量
    String name;
    private int age;

    //我们专门提供一个public修饰的setXxxx
   //这个方法的作用就是为属性设置值
    public void setAge(int a) {
        //正因为有了方法,我们可以在方法中对年龄的值控制
        if (a < 0) {
            System.out.println("年龄不能指定负值");
        return;//直接终止方法
        }
        age = a;
    }

    //我们专门提供一个public修饰的getXxxx
   //这个方法的作用就是为了获取属性的值
    public int getAge() {
        return age;
    }
}
public class PersonDemo {
    public static void main(String[] args) {
        Person person = new Person();//默认值:name=null;age=0

        //设置成员变量的name和age
        person.setName("三丰");
        person.setAge(100);

        //获取成员变量的name和age
        System.out.println(person.getName + " " + person.getAge());
    }
}

总结:

类中不需要对外提供的内容都私有化,包括属性和方法。

以后再描述事物,属性都私有化,并提供setXxxx和getXxxx方法对其进行访问。

注意:

私有仅仅是封装的体现形式而已。


关键字this

当方法中出现局部变量和成员变量同名的时候,需要在成员变量名前面加上this来区分成员变量和局部变量。

/*
* 利用getXxxx以及setXxxx来为Person类中的属性设置值和取值
* 当成员变量名和局部变量重名的时候,我们可以利用this关键字来区分
*/
public class Person {
    private String name;
    private int age;

    /*setName和getName*/
    /*
    *
    * 为了让形参名更加见名知意,我们不使用n变量名作为方法形参,我们就用name
    */
    public void setName(String name) {
        this.name = name;//this.name会使用成员变量
    }

    public String getName() {
        return name;
    }

    /*setAge和getAge*/
    public void setAge(int age) {
        this.age = age;//this.age会使用成员变量
    }

    public int getAge() {
        return age;
    }
}
public class PersonDemo {
    public static void main(String[] args) {
        method01();

    }

    private static void method01() {
        Person person = new Person();

        //设置成员变量的name和age
        person.setName("三丰");
        person.setAge(100);

        //获取成员变量的name和age
        System.out.println(person.getName() + person.getAge());
    }
}

继承

1.在Java中,类只支持单继承,不允许多继承。也就是一个类只能有一个直接父类。

2.多个类可以继承一个父类。

3.在Java中,可以多层继承,即一个类的父类可以再去继承另一个父类。

class A {}
class B {}
class C extends A,B {}   //语法错误,且不可以同时继承

子父类中成员变量的特点

父类的成员变量是非私有的,子类可以直接访问,若父类成员变量是私有的,则不能直接访问。

当子父类中出现多个同名变量,在子类若要访问父类中的同名变量,必须使用关键字super来完成。super关键字可以用来访问父类的非私有的成员。


成员变量和方法的访问特点

遵循就近原则。在访问成员变量或方法的时候,如果本类有该成员变量或该方法,直接使用,如果没有,继续查找父类。如果所有类都没有则报错。

子类(本类) =》 父类 =》 父类的父类 =》 Object

可以通过关键字super来调用父类的成员方法。

//子类中,访问父类中的成员方法格式:
super.父类中的成员方法();

方法重写

方法重写的必要条件:

1.必须有继承关系,重写针对的是子类的方法重写父类的方法。

2.子类的方法与被重写的父类的方法要保持一致(返回值类型,方法名,形参列表保持一致)。

3.子类的方法的权限 >=父类被重写的方法的权限。

public 默认 protected private

private修饰的方法不被重写,一旦修饰父类的方法,只能父类自己使用,子类根本获取不到。

@override

强制子类的方法重写父类的方法,如果不重写就报错。

public class Demo {}

class A {
    public void method(){}
}

class B extends A {
    @Override //强制重写
    public void method(){}
}

方法重写和方法重载的区别

//方法重载
public void show(int i) {
}

public void show(double j) {
}
//方法重写
public void method(double j) {
}

public void method(double j) {
}

1.权限修饰符

重载:对修饰符没有要求

重写:子类的方法的权限 >= 被重写的父类的方法权限

2.返回值类型

重载:对返回值类型没有要求

重写:子类的方法的返回值类型和父类的方法的返回值类型保持一致

3.方法名

重载:重载的两个方法的方法名保持一致

重写:重写要求子类的方法名和被重写的父类的方法名保持一致

4.形参列表

重载:重载要求两个方法的形参列表不一致(形参个数,形参类型,形参类型顺序)

重写:子类的形参列表和被重写的父类的形参列表一致


抽象

抽象引入

抽象方法引入:如果某个方法的方法体无法确定,我们需要把这个方法定义为抽象方法。

修饰符 abstract 返回值类型 方法名(形参列表);

抽象类引入:一旦一个类含有抽象方法,那么这个类必须是抽象类。

抽象类无法创建对象,因为抽象类里的抽象方法调用没有意义。

抽象类定义一般是作为体系的规范,约束子类必须实现父类的某些方法。

我们一般不直接使用抽象类而是通过创建它的子类对象去使用。


抽象产生

当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的功能具体实现方式,那么这些方法都有具体的方法体。

但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。比如一个图形类应该有一个求周长的方法,但是不同的图形求周长的算法不一样。那该怎么办呢?

分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。

当定义了抽象函数的类也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。


接口

概述

1.接口也是一种引用数据类型,引用数据类型可以赋值null或者对象(内存中的地址)。

2.接口的出现是为了弥补java中只有单继承的不足。

格式

//类的定义格式
class 类名{
    成员变量
    成员方法
}

//接口的定义格式
interface 接口名{
    成员变量
    成员方法
}

class 类名 implements 接口名{ //类与类使用extends,类与接口使用implements
    
}

接口和抽象类一样,都不能创建对象。

接口编译之后也是生成 接口名.class文件

接口中的变量必须初始化才能定义(接口中的成员变量加的有默认修饰符:public static final)

static修饰的成员可以通过类名或者接口名直接调用 接口名/类名.成员变量。

final修饰的变量都是常量(只能赋值一次)。

接口中的成员方法

1.抽象方法

在接口中,定义抽象方法可以不用加public abstract,编译器默认会加。

interface MyInter{
    public abstract void method();
    void show();
}

class A implements MyInter{
    @Override
    public void method() {
        System.out.println("A实现了MyInter方法");
    }

    @Override
    public void show() {
        System.out.println("A实现了show方法");
    }
}

public class Demo03 {
    public static void main(String[] args) {
        A a = new A();
        a.method();
        a.show();
    }
}


//执行结果
A实现了MyInter方法
A实现了show方法

2.默认方法

JDK8及以上版本才能定义默认方法

默认方法可以有方法体

默认方法可以被子类重写

当我们在接口中添加默认方法,所有的子类可以直接沿用,不需要再修改子类的代码,提高了代码的复用性。

default 返回值类型 方法名(形参列表) {
}

3.私有方法

JDK9及以上版本才能在接口中定义私有方法。

接口中的私有方法只能在本接口中使用,不能被子类使用

private 返回值类型 方法名(形参列表) {}

类与接口

一个类可以实现多个接口(一个类只能继承一个类)

//格式

class 类名 implements 接口1,接口2,...{
    //重写方法
}

一个类可以继承另一个类同时实现多个接口

//格式

class 类名1 extends 类名2 implements 接口1,接口2,...{
    
}

一个接口可以继承多个接口

//格式

interface 接口名1 extends 接口名2,借口名3,... {
    
}

多态

多态概述

多态就是一个对象的多种形态。(婴儿,学生,父亲,爷爷)

多态体现

向上转型(子类型自动提升父类型)

不能将父类对象 赋值给子类型

普通类的向上转型:父类型 引用变量名 = new 子类();

Dog dog = new Dog();//我们看到一条狗,把它称作狗
Animal anmial = new Dog;//我们看到一只狗,把它称作动物

Dog dog = new Animal();//语法有误,我们看到一只动物,我们把它叫作狗

抽象类的向上转型:抽象父类型 引用变量名 = new 子类();

Teacher teacher = new Teacher();//存在一位老师,叫他老师
Person person = new Teacher();//存在一位老师,叫他人
Teacher teacher = new Person();//语法有误,存在一个人,叫他老师

接口的向上转型:父接口型 引用变量 = new 实现类();

Smoking smoking = new Student();//有个学生,抽烟

向下转型

格式:子类型 引用变量 = (子类型) 父类型引用变量 ;

(类似: int i = (int)d)

/*
*这个例子中我们只有一个学生对象
*但是这个学生对象扮演了两种角色,分别是人和学生
*当扮演人的角色的时候就具有人的行为
*当扮演学生的角色的时候就具有学生的行为
*/
class Person {
    public void eat() {
        System.out.println("吃东西");
    }
}

class Student extends Person {
    public void study() {
        System.out.println("学java");
    }
}

public class Demo {
    public static void main(String[] args) {
        Person person = new Student();//我们把生活中的一个学生看成一个人
                                      //类比基本数据类型:double d = 3; (int =>double)
                                      //把父类型看成大类型,把子类型看成小类型
                                      //Student =>Person
        person.eat();//由于p指向的学生对象扮演的是人的角色,所以可以调用Person类中的方法。p.study();由于p指向的学生对象扮演的是人的角色,但是Person类不具有学生的学习方法,不能调用。
        Student student = (Student) person;//类比基本数据类型:int i = (int)d     (double => int)
                                           //Person => Student
        student.eat();//把s指向的学生对象扮演的是学生角色,所以可以调用学生类中的方法
        student.study();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值