Java(三)面向对象的特性

Java(三)面向对象的特性

构造方法生成小技巧:使用idea时,在代码空白处单击右键,选择Generate选项,之后再选择Constructor生成构造器,也可以使用toString()来重写这个函数。

继承

  • 父类也称为超类、基类、派生类等
  • Java中只有单继承,没有像C++那样的多继承,多继承会引起混乱,使得继承过于复杂,系统难于维护
  • Java中没有多继承,但接口有多继承
  • 子类继承父类,可以得到父类的全部属性和方法(除了父类的构造方法),但不见得可以直接访问(比如:父类私有属性和方法)
  • 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Objetct
package cn.yhq.oo; //非注释语句第一句

public class User {
    public static void main(String[] args) {
        Student stu1 = new Student(20,"自动化","yhq","体育课");
        stu1.learning();
        stu1.showMajor();
    }
}
class Person{
    int age;
    String name;
    String major;
//父类中不能含有参构造,如果要继承的话
//    Person(int age,String name,String major){
//        this.name = name;
//        this.age = age;
//        this.major = major;
//    }

    public void showMajor(){
        System.out.println("我的专业是"+major);
    }
}
class Student extends Person{
    String lesson;
    public Student(int age,String major,String name,String lesson){
        this.major = major;
        this.name = name;
        this.age = age;
        this.lesson = lesson;
    }
    public void learning(){
        System.out.println("我在上课呢"+name+lesson);
    }
}

可以使用idea的功能可以方便查看类的继承结构

instanceof方法

​ 使用instanceof可以判断对象是否归属于某个类:

Student stu1 = new Student(20,"自动化","yhq","体育课");
        System.out.println(stu1 instanceof Person);
        System.out.println(stu1 instanceof Object);
        System.out.println(new Person() instanceof Object);
方法重写(override)

​ 子类通过重写父类的方法,可以使用自身的行为替换父类的行为。 方法重写需要符合下面三个要点:

  • “==“:方法名、形参列表相同
  • “<=”:返回值类型和声明异常类型,子类小于等于父类
  • ”>=“:访问权限,子类大于等于父类
class Vehicle{
    int speed;
    public void showTheType(){
        System.out.println("嗡嗡嗡");
    }
    public Person whoIsPsg(){//父类类型为Person,子类的类型要小于Person
        return new Person();
    }
}
class Horse extends Vehicle{
    public void showTheType() {
        System.out.println("马叫");
    }

    public Vehicle method(){
        return new Vehicle();
    }
    public Person whoIsPsg(){ //返回值类型小于父类的类型,如果是Object就会报错
        return new Student();
    }
}
Object类

​ object类是所有Java类的根基类,也就意味着所有的Java对象都拥有Object类的属性和方法。其中toString()是用于返回以一个字符串表示的对象值,是一种自我描述的方法,一般通过重写来打印所需要的内容。

public class TestObject {
    public static void main(String[] args) {
        TestObject to = new TestObject();
        System.out.println(to.toString());

        Person2 p2 = new Person2("喜喜",6);
        System.out.println(p2.toString());

    }
    public String toString(){ 
        return "Test Obeject 对象";
    }

}
class Person2{
    String name;
    int age;
    public String toString(){ 
        return name+"年龄"+age;
    }
    public Person2(String name,int age){
        this.name = name;
        this.age = age;
    }

}
==和equals方法

==代表比较双方是否相同,如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。

Object类中定义有:public boolean equals(Object obj)方法,提供定义"对象内容相等"的逻辑。equals的源代码为:

    public boolean equals(Object obj) {
        return (this == obj);
    }

重写equals代码:

package cn.yhq.oo;

import java.util.Objects;

public class TestEquals {
    public static void main(String[] args) {
        Object obj;
        String str;

        User03 u1 = new User03("yhq","123456");
        User03 u2 = new User03("yhq","123456");

        System.out.println(u1==u2);//这表示不是同一个对象,结果为false
        System.out.println(u1.equals(u2));//判断两个对象是否相同时吗,通常是判断其id是否相同
    }
}
class User03{
    String username;
    String pwd;

    public User03(String username, String pwd) {
        this.username = username;
        this.pwd = pwd;
    }

    public String toString() {
        return "User03{" +
                "username='" + username + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User03 user03 = (User03) o;
        return Objects.equals(username, user03.username);
    }

}
super关键字

​ super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。构造方法的第一句总是:super(…)来调用父类对应的构造方法。所以流程是:

1.先向上追溯到Object

2.然后再依次向下执行类的初始化块和构造方法

3.执行到当前子类位置

静态初始化块调用顺序和构造方法调用顺序一致,不再重复

package cn.yhq.oo;

public class TestSuper {
    public static void main(String[] args) {
        SonClass son = new SonClass();
        son.work();
        son.superWork();
    }
}
class FatherClass{
    String name;
    int age;
    FatherClass(){
        System.out.println("fatherClass");
    }
    void work(){
        System.out.println("father work");
    }
}
class SonClass extends FatherClass{
    //每个类的第一句话都是super(),自动调用父类的构造函数
    SonClass(){
        System.out.println("SonClass");
    }
    void work(){
        System.out.println("Son work");
    }
    void superWork(){
        super.work();
    }
}

封装

封装

类的定义规则

1.一般使用private访问权限。

2.提供相应的set、get方法来访问相关的属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作。

3.一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法用public修饰。

package Test;

//成员变量全部换位public
public class Person4 {
    private int id;
    private String name;
    private int age;
    private boolean man;

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public void setAge(int age){
        if (age>=1&&age<=130){
            this.age = age;
        }else {
            System.out.println("请输入正常年龄");
        }
    }
}

类中只包含set和get方法,这种类称为JavaBean,一个类中除了set和get之外的方法,一般都是用public,除了写包时候。

多态(polymorphism)

​ 多态指的是同一个方法的调用,由于对象不同可能会有不同的行为,现实生活中,同一个方法,具体实现会完全不同。

多态是指方法的多态

多态的要点:

1.多态是方法的多态,不是属性的多态(多态和属性无关)。

2.多态的存在要有三个必要条件:继承、方法重写、父类引用指向子类对象。

3.父类引用指向子类对象后,用该父类引用调用子类重写方法,此时多态就出现了。

package Test;

public class TestPoly {
    public static void main(String[] args) {
    
        Animal a = new Animal();
        animalCry(a);//父类对象指向子类

        Dog d = new Dog();
        animalCry(d);

        Cat c = new Cat();
        animalCry(c);

    }
    static void animalCry(Animal a){ //传入不同对象执行方法不同
        a.shout();
    }

}
class Animal{
    public void shout(){
        System.out.println("叫了一声!");
    }
}
class Dog extends Animal{
    public void shout(){
        System.out.println("旺旺");
    }
}
class Cat extends Animal{
    @Override
    public void shout() {
        System.out.println("喵喵");
    }
}
自动向下转型
Animal d = new Dog();	//自动向上转型:dog转成animal类,这里要注意类型是animal类,但是对象是Dog。
Dog d2 = (Dog)d;	//强制向下转型:animal转为dog

//猫强转成dog,会产生编译错误
Animal c = new Cat();
Dog d3 = (Dog)c;

final修饰

final关键字作用:

1.修饰变量:被修饰得变量不可以改变,一旦赋值,就不能重新赋值。

final int MAX_SIZE = 120;

2.修饰方法:该方法不可被子类重写,但是可以被重载!

final void study(){}

3.修饰类:修饰的类不能被继承。比如:Math、String

final class A{}

数组(也为对象)

​ 数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称为一个元素,每个元素可以通过一个索引来访问。

特点

  • 长度是确定的,数组一旦被创建,它的大小就是不可改变的
  • 其元素必须是相同的,不允许出现混合类型
  • 数组类型可以是任何数据类型,包括基本类型和引用类型

数组变量属于引用类型,数组也属于对象,数组中每个元素相当于该对象的成员变量。

声明方式

type[] arr_name;//推荐使用这种方式

注意事项

  • 声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关。
  • 声明一个数组的时候并没有数组真正被创建
  • 构造一个数组,必须指定长度
package cn.yhq.array;

public class Test01 {
    public static void main(String[] args) {
        //int[] arr01:这是数组的声明,int[] arr01 = new int[10];这是数组的初始化
        int[] arr01 = new int[10]; //索引下标[0 length-1]:
        String[] arr02 = new String[5];
        User[] arr03 = new User[3];

     arr03[0] = new User(100,"yhq"); //不是将对象直接放到数组,是存放对象地址
        arr03[1] = new User(101,"tony");
        arr03[2] = new User(102,"jenny");

        for (int i = 0;i<arr03.length;i++){
            System.out.println(arr03[i].getAge());
        }


    }
}
class User{
    private int id;
    private  String age;

    public User(int id, String age) {
        this.id = id;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAge() {
        return age;
    }

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

数组存储方式

不是将元素对象直接放到数组,是存放对象地址

初始化方式

  • 静态初始化
  • 动态初始化
  • 默认初始化
package cn.yhq.array;

public class Test02 {
    public static void main(String[] args) {
        //静态初始化
        int[] a = {2,3,4};
        User[] user01 = {
                new User(100,"19"),
                new User(101,"20")
        };
        //默认初始化
        int[] b = new int[3];//默认给数组的元素进行赋值。赋值的规则和成员变量赋值的规则一样

        //动态初始化
        int[] a1 = new int[2];//动态初始化数组,先分配空间
        a1[0] = 1;//给数组元素赋值
        a1[1] = 2;
    }
}

数组遍历

​ 增强for循环for-each是专门用于读取数组或者集合中所有的元素,即对数组进行遍历。

 //foreach循环:用于读取数组元素的值,不能修改元素的值
        for (int m:num_array){
            System.out.println(m);
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值