Java--面向对象入门理解

创建与初始化对象

使用new关键字创建对象

使用new关键字创建对象的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。

类中的构造器也称为构造方法,是在创建对象的时候必须要调用的。并且构造器有以下两个特点:

  • 必须和类的名字相同

  • 必须没有返回类型,也不能写void

  • this代表当前类,如this.name, this.age

面向对象编程**(Object Oriented Programming)**的实质是:以类的方式组织代码,以对象的方式封装数据

类与对象:

  • 类是一个模板,抽象性强
  • 对象是一个具体的实例,是基于特定模板创建的,个性化明显。对象是通过引用来操作的:栈–>堆

类中的属性,也称为字段field、成员变量

默认的初始化:

  • 数字:int 0;float:0.0
  • char:\u0000
  • boolean:false
  • 引用:null

属性的创建:

qualifier修饰符 属性类型 属性名 = 属性值  // 属性类型包括:基本类型(8),引用类型

继承

  • 所谓”道生一,一生二,二生万物“,所以尽管我们定义的某一个类是抽象的模板,但是还可以对这些类进一步抽象,产生进一步抽象的类。在java中,有一个终极类 ,叫做object,其他类都直接或间接继承这一个类。

  • 子类继承父类,使用关键字child extends Parent()来表示继承父类的子类。

  • Java中只有单继承,没有多继承。(即只有一个直接父亲,其他的都是祖宗)

super和this的使用

  • super()、 super.attribute/methodsuper指向当前类继承的父类的实例对象,而非类对象。
  • this() this.attribute/method,this可以在任何类中使用。this指向当前类的实例对象,如this.name, this.age,相当于python中的self
  • 类的静态属性静态方法中不能用thissuper,此时直接用类名即可。

继承案例代码

package com.benjamin.OOB;

public class Application {
    public static void main(String[] args) {
//        Student student01 = new Student("Xiaoming", "male");
//        Student student02 = new Student("Xiaohong", "female");
//
//        student01.setAge(5);
//        student02.setAge(6);
//
//        System.out.println(student01.getName()+" is a "+student01.getGender()+" child, "+student01.getAge()+" year old.");
//        System.out.println(student02.getName()+" is a "+student02.getGender()+" child, "+student02.getAge()+" year old.");

        Student student = new Student();
    }
}

// =================================Student类=================================
package com.benjamin.OOB;

public class Student extends Person {
    // 设定属性私有,通过get/set进行管理访问,这本质上就是"封装"
    private String name;
    private int age;
    private String gender;

    // this代表当前这个最直接的对象
    // super代表父类(最直接继承的对象)

    public Student() {
        //super()调用的是父类的构造器(有参无参都可以,要灵活应对)
        // super()必须放在子类构造器的“第一行”
        // 如果当前类继承了父类,即使在该类的构造器中不显示的写出super(),编译器也会自动为我们加上super()这个声明
        super();
        // this()是调用本类的构造器(有参无参都可以,要灵活应对)
        // 调用this也必须放在该构造器主题内容的第一行;所以不能同时调用super()和this()
        //this("zhangsan","male");
        System.out.println("Student的无参构造器执行完成");
    }

    // constructor
    public Student(String name,String gender){
        this.name = name;
        this.gender = gender;
    }

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

    public int getAge(){
        return this.age;
    }
    public void setAge(int age){
        if(age > 120 || age < 0){
            age = 3;
            System.out.println("Stupid number");
        }
        else{
            this.age = age;
        }
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

// =================================Person类====================================
package com.benjamin.OOB;

public class Person {
    String name;
    int age;

    // 使用new本质上是在调用构造器(构造函数/构造方法)
    // 构造器用来初始化属性、进行一些操作
    // 注意:
    // *******必须没有返回类型,但不能写void************
    // 构造函数名必须和类名相同
    public Person() {
        System.out.println("Person的无参构造器执行完成");
    }

    // 一旦定义了有参构造,无参构造必须显示定义(这是因为当我们一旦开始定义构造函数时,编译器就不再自行定义构造函数了)
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // Alt + Insert可以利用IDE提供的快捷方式快速显示定义构造函数
    // 构造器(函数)可以有很多个,本是上就是方法重载,由编译器来判断我们想要哪一个
}

方法重写

重写都是子类针对父类的方法
重写需要满足:

  1. 方法名必须相同;
  2. 参数列表必须相同
  3. 修饰符范围可以扩大,但不能缩小 public > protected> default > rivate
  4. 抛出异常:范围可以缩小,但不能扩大。

重写多态的前提和基础。

多态

一个对象的实际类型是确定的,但是指向实际对象的引用类型有很多,如该类引用父类引用祖宗引用都可以指向当前实例对象。

多态注意事项

  • 多态是方法的多态,属性没有多态
  • 有继承关系,且方法需要重写
  • 多态实例化方法:Father f1 = new Son();

不能被重写的方法:

  • static标识的方法
  • final修饰的方法
  • private修饰的方法

代码说明

// ====================================Application类================================================
package com.benjamin.OOB;

import com.benjamin.OOB.Demo02.Person;
import com.benjamin.OOB.Demo02.Student;

public class Application {
    public static void main(String[] args) {
        // 一个对象的的实际类型是确定的
        // 但与之建立的引用类型就不一定是唯一的,该对象的引用类型可以是该类型、父类或祖宗类
        Student s1 = new Student();

        // 一个对象能执行哪些方法,与定义时左边的引用类型有关,这个引用类型划定了可以使用的属性和方法的范围。
        // new Student()时,创建了一个Student对象,这个Student对象的内容包含了其父类Person的方法和属性
        // 左边的Person s2 规定了 s2 可以引用的内容仅限 Person 里有的属性和方法(如果有重写的方法,则用子类重写的方法)
        // 注意和 Person s2 = new Person() 这种普通方式创建类的区别
        // 这就是“多态”
        Person s2 = new Student(); // 打印:run==>Student
        Object s3 = new Student(); // 打印:run==>Student

        s1.run();
        s2.run();
        System.out.println("================");
        System.out.println("s1 "+s1.age); // 打印:s1 5
        System.out.println("s2 "+s2.age);// 打印:s2 10
        // 这说明多态是方法是多态,属性不存在多态
        // 子类在创建对象时,父类属性和子类属性的内容会同时创建,即使同名属性也可以同时存在
        System.out.println("================");

        // 由于 s2 不能直接利用子类独有的方法,所以必须强制向下类型转换
        ((Student) s2).eat();
        // 打印:
        // eating!
        // Person's age: 10

    }
}
//=============================================以下是Student类==========================================
package com.benjamin.OOB.Demo02;

public class Student extends Person{

    public int age = 5;
    @Override
    public void run() {
        System.out.println("run==>Student");
    }

    public void eat(){
        System.out.println("eating!");
        System.out.println("Person's age: "+super.age);
    }
}
// =============================================以下是Perosn类===========================================
package com.benjamin.OOB.Demo02;

public class Person {
    public int age = 10;
    public void run(){
        System.out.println("run==>Person");
    }
}

instanceof 理解

字面理解:判断是否为某一类的实例,返回布尔值

代码里理解:

// ====================================Application类================================================
package com.benjamin.OOB;

import com.benjamin.OOB.Demo02.Person;
import com.benjamin.OOB.Demo02.Student;
import com.benjamin.OOB.Demo02.Teacher;

public class Application {
    public static void main(String[] args) {
        // 继承关系如下
        // Object > String
        // Object > Person > Teacher
        // Object > Person > Student


        Object object = new Student();

        // 虽然 Student 类从父子类的角度将在下游,但是从内容的丰富性来讲,越是下游,丰富度越高
        // 这也是多态产生的关键原因
        // 所以父类类型引用可以指向子类模板实例化产生的对象
        // 再来分析具体的问题:
        // new Student创建对象之所以能成功,离不开Object类、Person类、Student类的模板化引导
        // 所以object引用类型指向的对象可以说都是Student类、Person类、Object类的实例,故为true
        // 相反,new Student创建对象和Teacher类、String类没有任何关系
        // 所以object引用类型指向的对象不是Teacher类、String类的实例,故为false
        System.out.println(object instanceof Student); // true
        System.out.println(object instanceof Person);  // true
        System.out.println(object instanceof Object);  // true
        System.out.println(object instanceof Teacher);  // false
        System.out.println(object instanceof String);  // false

        // 下面的分析思路同理
        Person person = new Student();
        System.out.println(person instanceof Student); // true
        System.out.println(person instanceof Person);  // true
        System.out.println(person instanceof Object);  // true
        System.out.println(person instanceof Teacher);  // false
        //System.out.println(person instanceof String);  // false

        Student student = new Student();
        System.out.println(student instanceof Student); // true
        System.out.println(student instanceof Person);  // true
        System.out.println(student instanceof Object);  // true
        //System.out.println(student instanceof Teacher);  // false
        //System.out.println(student instanceof String);  // false

    }
}
// ======================================以下是Student类=======================================
package com.benjamin.OOB.Demo02;

public class Student extends Person{

    public void run(){
        System.out.println("=====run=====");
    }
}
// ======================================以下是Teacher类=======================================
package com.benjamin.OOB.Demo02;

public class Teacher extends Person{
}
// ======================================以下是Person类=======================================
package com.benjamin.OOB.Demo02;

public class Person {
    public void go(){
        System.out.println("=====go=====");
    }
}

引用类型转换

子类引用类型转换为父类引用类型,可以平滑转换,因为子类引用对应的内容圈更大,父类引用对应的内容圈相对较小,以大转小很自然,相当于水自然而然向下流(势能高的原因),代价就是损失一些子类特有的方法和属性。

Parent parent = child; // child是子类引用类型,parent是新定义的父类引用类型。

父类引用类型转换为子类引用类型,由于要扩大自己的内容圈,相当于要把水流由低处抽送到高处,这是要费力做工才能实现的,所以要强制转换。

Child child = (child)parent; //和8个基本类型的强制转换 格式一致。在被转换的类型前面加上 (目标引用类型)

static静态理解

static既可以修饰类属性,又可以修饰类方法。由于是固定不变的,所以共用一份就可以。

// =============================Application类=====================================
package com.benjamin.OOB;

import com.benjamin.OOB.Demo02.Person;
import com.benjamin.OOB.Demo02.Student;
import com.benjamin.OOB.Demo02.Teacher;
import com.benjamin.OOB.Demo03.Static;

public class Application {
    public static void main(String[] args) {
        Static s1 = new Static();
        System.out.println("***********************");
        Static s2 = new Static();
    }
}
// =============================Static类==========================================
package com.benjamin.OOB.Demo03;

public class Static {
    {
        // 2. 匿名代码块可以赋初值
        System.out.println("匿名代码块 anonymity code block");
        System.out.println("====================");
    }
    static{
        // 1. static代码块只执行一次
        System.out.println("静态代码块 static code f1");
        System.out.println("====================");
    }


    public Static() {
        // 3.
        System.out.println("构造器代码块 constructor code block");
        System.out.println("====================");
    }
}

内部类

在类的内部再定义一个类,这个类中类就称为内部类。

抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
  • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类抽象类不能使用new关键字来创建对象,它是用来让子类继承的。
  • 抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
  • 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
//=================================Application类====================================

package com.benjamin.OOB;

import com.benjamin.OOB.Demo03.Concrete;

public class Application {
    public static void main(String[] args) {
        Concrete concrete = new Concrete();
        concrete.doSomething();
    }
}
// ================================以下是Concrete类========================================
package com.benjamin.OOB.Demo03;

public class Concrete extends Abstract { 
    public void doSomething(){  // 子类必须实现抽象父类的抽象方法
        System.out.println("I've made it come true");
    }
}
// =================================以下是Abstract类========================================
package com.benjamin.OOB.Demo03;

public abstract class Abstract {
    // abstract, 抽象方法,只有方法的声明,没有方法的实现
    public abstract void doSomething();

    // 1. 不能new这个抽象类,只能靠子类来实现它
    // 2. 抽象类中可以写普通的方法
    // 3. 抽象方法必须在抽象类中

    // 抽象类存在构造器吗?抽象类的意义是什么?
}

接口

声明类的关键字是class,声明接口的关键字是interface

接口抽象方法常量值的定义的集合。

  • 普通类:只有具体的实现;
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范!接口内部绝不写实现的具体方法,专业级约束。约束和实现分离:面向接口编程~

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是… , 则必须能…”的思想。

接口的本质是契约,就如同法律一样,制定好后大家都需要遵守。

//==================================接口1定义======================================
package com.benjamin.OOB.Demo04;

public interface UserService {  // 用interface标识接口

    //java接口中定义的所有方法其实都是抽象方法 public abstract
    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}


//===================================接口2定义======================================
package com.benjamin.OOB.Demo04;

public interface TimerService {
    void timer();
}


//====================================接口抽象方法的具体实现===========================
package com.benjamin.OOB.Demo04;

// 类可以实现接口定义的方法:implements 接口
// 实现接口的类,就需要重写接口中的方法
// 侧面实现了多继承~
public class UserServiceImpl implements UserService,TimerService{

    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void timer() {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值