天天看点

Java个人学习笔记心得之面向对象

构造器(构造方法)

方法名和类名一样,但是没有返回值,void也不能加

**最好:**一个类如果重写了有参构造,那么最好机上一个无参构造,如果不加,可能会在继承关系中出错

作用:

  1. 使用new关键字,必须要有构造器(本质是在调用构造器)
  2. 一旦定义了一个有参构造,那么无参构造必须显示定义
  3. 一般用来初始化值

语法:

public class hello {
    public String _name;
    private int _age;
    //构造器,也叫构造方法
    public hello(String name, int age) {
        this._name = name;
        this._age = age;
    }
}
           

在这里,_age是私有的,哪怕在构造器赋了值,在别的类中创建对象也还是调用不了,而 _name就可以

面向对象三大特性:

(有继承才有重写,有重写才有多态)

封装:

意义:

  • 提高程序的安全性,保护数据
  • 隐藏代码的实现细节
  • 统一接口
  • 系统可维护性增加

封装(数据的隐藏):

通常,应禁止直接访问一个对象中的数据的实际表示,而应通过操作接口来访问,这成为信息隐藏

记住这句话就够了:属性私有,get/set

示例:

在hello这个类中给它的属性封装:

public class hello {
    //属性私有
    private String name;
    private int age;
    //提供一些可以操作这个属性的方法
    //提供一些public的get和set方法

    //封装的get方法,返回值为封装属性的类型,且封装属性的首字母大写
    //get 获得返回的这个数据
    public String getName(){
        return this.name;
    }
    //封装的set方法,返回值为void,提供给外部进行的操作,属性首字母大写
    //set 给这个属性设置值,也可以加上条件对不合法的起输入限制作用
    public void setName(String name){
        this.name =name;
       }
}
           

在另一个类中,实例化hello类的对象,调用它的封装属性:

hello h= new hello();
 h.setName("王志凯");//在另一个类通过设置的方法给属性设值
 System.out.println(h.getName());//得到返回的值,并且输出
           

结果:

王志凯

继承:

在Java中所有的类都是object的子类。默认继承object类

在Java中类只能单继承,没有多继承

语法:

extends:扩展。子类是父类的扩展

public class Student extends Person {
}
           

super:

注意点:

  • super调用父类的构造方法,必须在构造方法的第一个
  • super必须只能出现在子类的方法和或者构造方法中
  • super和this不能同时调用构造方法

super VS this

  • 代表的对象不同

this:本身调用者这个对象

super:代表父类对象的应用

前提:

this:没有继承也可以使用

super:只能在继承条件下才能使用

构造方法的区别:

this():调用本类的构造方法

super():调用父类的构造方法

重写(override):

重写就是在子类里创建一个和父类中相同的方法,但是里面的方法体不同,这样子,在对象调用的时候,就会调用到子类重写的方法,而不会调用到父类的相同的方法

  1. 需要有继承关系,子类重写父类的方法
  2. 方法名必须相同,方法体可以不同
  3. 参数列表必须相同
  4. 修饰符:范围可扩大,public>Protected>Default>private
  5. 抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException–>Exception
  6. 重写都是方法的重写,和属性无关,私有的方法无法重写
  7. 非静态的方法才能被重写

静态方法:方法的调用只和左边定义的数据类型有关

**非静态方法:**才叫重写

思考:为什么需要重写?

答:父类的功能子类不一定需要,或者不一定满足,所以需要子类把父类的方法重写一下,加上自己需要的功能

示例:

Application类:

public class Application {
    public static void main(String[] args) {
        Student s = new Student();//重点关注这里
        s.test();
        Person p = new Student();//重点关注这里
        p.test();
    }
}
           

Person类:

public class Person {
    public static void test(){

 System.out.println("person的test");
    }
}
           

Student类:

public class Student extends Person {
    public static void test(){

    System.out.println("student的test");
    }
}
           

输出的结果:

student的test

person的test

**解析:**这说明,当方法是静态方法的时候,调用方法只与 Student s 和 Person p有关,也就是说当是静态方法时,调用的方法只和实例化语句中的:

Student s = new Student();
           
Person p = new Student();
           

左边相关,是哪个类就是哪个类的方法,否则就是new的类的方法。

多态:

  1. 即同一方法可以根据发送对象的不同采用多种不同的行为方式
  2. 一个对象的 “实际类型”(如:new Person())是确定的,但可以指向对象的 “引用类型”(如:Person p )有很多
  3. 多态存在的条件:
  • 有继承关系
  • 子类重写了父类方法
  • 父类的引用指向子类对象
A a= new B();
           

*

注意:

  • 多态是方法的多态,属性没有多态性
  • 如果父类的引用类型指向得失子类的对象,那么通过父类的引用类型来调用的方法还是可以实现父类的功能的,虽然是指向了子类的,但因为子类是继承了父类的方法的。
  • 静态方法:方法的调用只和左边定义的数据类型有关
  • **非静态方法:**才能重写

通俗的说就是:

对象能执行的那些非静态的方法,主要看对象左边的类型,和右边的关系不大,只有左边的类型有的非静态的方法才可以实现,只有右边有的方法没办法实现。

B a= new B();//B 能调用的方法都是自己的或者继承父类A的
A a= new B();//A 父类型的引用,可以指向子类,但是不能调用子类独有的方法。
           

有static静态,final常量,private私有修饰符的无法重写,自然也就没有多态

Instanceof

语法:A Instanceof B

A和B有关系吗?有true,没有false

用法:

有一个Student类继承extends父类Person

Object o = new Student();
 System.out.println(o instanceof Student);
 System.out.println(o instanceof Person);
 System.out.println(o instanceof Object);
 System.out.println(o instanceof String);
           

结果:

true

true

true

false

类型转换:

高转低要强制转换,低转高自动转换

父类高于子类

语法:

(Person)Student

Static

当访问的类中的变量是static变量时候,可以直接通过类名.来访问这个成员。

static方法只会在一开始加载一次,之后不会再加载

抽象类:

  • 抽象类,只有抽象方法,没有方法体。
  • 子类如果继承了抽象类,那么抽象类的所有方法,子类都要去实现。(如果子类也是abstract,那就不用)

特点:

  • 不能new出来这个抽象类,只能靠子类去实现它
  • 抽象类只可以写方法,没有方法体
  • 抽象方法必须在抽象类中

个人思考:

抽象类真正的作用是为了实现,他的目的是当父类某种方法毫无意义,但是又必须要有的时候占个位置,提醒子类一定要去实现。打个比方,电器有耗电标准,但是笼统的电器(父类)的耗电标准是毫无意义的,只有具体到实际的某种电器(子类)才有意义,所以干脆就不在电器(父类)中写,由具体的电器(子类)来完成,但是耗电标准又是必须得实现的,所以需要电器(父类)为之提醒。这也是跟实际生活相符合的结果,是面向对象思维的体现。

(****就是当这个父类是抽象类的时候里面定义了一个抽象函数(在返回值前面加上abstract),里面的函数没有方法体,因为父类不知道每个子类需要实现什么方法,所以子类只需要创建一个和父类相同的函数方法,表示重写父类的抽象方法,就可以自己来实现自己特有的函数方法体,而且子类必须都要重写一遍抽象类(父类)的抽象方法****)

语法:

abstract

public abstract class Application {
public abstract test();//没有方法体
}
           

接口:

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

接口连构造方法都没有,自然没法被实例化

普通类:只有具体的实现

抽象类:具体实现和规范(抽象方法)都有

接口:只有规范!自己无法写方法,专业的约束,约束和实现分离

  • 接口就是规范,定义得是一组规则,体现了现实世界“如果你是…则必须能…”的思想,如果你是天使,则必须能飞,如果你是汽车,则必须能跑,如果你是好人,则必须干掉坏人,如果你是坏人,则必须欺负好人
  • 接口的本质是契约,就像我们人间的法律一样,制定好后,大家都遵守
  • OO的精髓,是对对象的抽象,最能体现这一点的就是接口

语法:

interface 定义接口的关键字,代替class

implements 类继承接口的关键字

示例:

UserService接口:

//interface 定义的关键字
public interface UserService {
    //接口中的所有定义其实都是抽象的 public abstract
     void run(String name);//可以不写public
     void delete(String name);
     void update(String name);
}
           

Teacher接口:

public interface Teacher {
    void teach();
    void classBegin();
}
           

UserServiceImp继承接口的类:

  • 类可以实现接口, implements 实现接口
  • 实现了接口的类,就需要重写接口的方法
  • 接口可以实现多继承
//类可以实现接口, implements 实现接口
//实现了接口的类,就需要重写接口的方法
//接口可以实现多继承
public class UserServiceImp implements UserService,Teacher {
    //UserService接口的抽象接方法,子类重写接口的抽象方法
    @Override
    public void run(String name) {
        System.out.println("我是运行");
    }
    @Override
    public void delete(String name) {
        System.out.println("我是删除");
    }
    @Override
    public void update(String name) {
        System.out.println("我是更新");
    }
    //Teacher接口的抽象方法,子类重写接口的抽象方法
    @Override
    public void teach() {
        System.out.println("我是教学");
    }
    @Override
    public void classBegin() {
        System.out.println("我是上课");
    }
}
           

内部类:

  • 在一个类的内部在定义一个类就是内部类,对于内部类来说,外面的类就是外部类
  • 内部类可以实现外部类的私有属性

用法:

要使用内部类,先要实例化外部类的对象,然后通过对象来实例化内部类

实例化外部类:

Student t = new Student();
           

实例化内部类:

Student t = new Student();
t.hand hand= t.new hand();//实例化内部类