Java面对对象编程

  • Java面对对象编程
  • 初识面向对象
  • 方法回顾和加深
  • 类与对象
  • 对象的创建分析
  • 面对对象三大特性
  • static详解
  • 抽象类和接口
  • 内部类
  • 笔记


Java面对对象编程

初识面向对象

属性+方法 = 类

  • 面向过程思想
  • 步骤清晰简单。第一步做什么,第二步做什么
  • 面对过程适合处理一些较为简单的问题
  • 面对对象思想
  • 物以类聚,分类的思维模式,思想问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节及面对过程的思索、
  • 面对对象适合处理复杂的问题,适合处理需要多人协作的问题
  • 对于描述复杂的事物,未来从宏观上把、从整体上分析,我们需要使用面对对象的思路来分析整个系统。但是,具体到微观操作,仍然举要面对过程去处理
  • 面向对象编程(Object-Oriented Programming,OOP)
  • 面对对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
  • 核心:抽象
  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象
  • 从代码运行角度考虑是现有类后有对象。类是对象的模板
package OOP.Demo01;

//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {

        //类:抽象的,实例化
        //类实例化后会返回一个自己的对象
        Student xm = new Student();
        Student xh = new Student();

        xm.name = "xiaoming";
        xm.age = 18;

        System.out.println(xm.name);
        System.out.println(xm.age);

        xh.name = "xiaohong";
        xh.age = 18;

        System.out.println(xh.name);
        System.out.println(xh.age);
    }
}
package OOP.Demo01;

public class Student {
    //属性
    String name;//null
    int age;//0

    //方法
    public void study(){
        System.out.println(this.name + "在学习");
    }
}

方法回顾和加深

  • 方法的定义
  • 修饰符
  • 返回类型
  • break 和 continue
  • 方法名
  • 参数列表
  • 异常抛出
  • 方法的调用
  • 静态方法
  • 非静态方法
  • 形参和实参
  • 值传递和引用传递
  • this关键字

类与对象

  • 类是一种抽象的数据类型,它是对某一事物整体描述、定义,但是并不能代表某一具体事物
  • 动物、植物、手机、电脑…
  • Person类、Pet类、Car类等,这些类都是用来描述/定义某一类具体事物应该具备的特点和行为
  • 对象是抽象概念的具体实例
  • 张三是人的实例,旺财是狗的实例
  • 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念
//小结
/*
1.类和对象
    类是一个模板;抽象,对象是一个具体的实例
2.方法
    定义、调用
3.对应的引用
    引用对象:   基本类型(8)
    对象是通过引用来操作的:栈 --> 堆
4.属性: 字段Field 成员变量
    默认初始化
        数字  0   0.0
        char    u0000
        boolean     false
        引用  null

   修饰符 属性类型 属性名 = 属性值;
5.对象的创建和使用
    - 必须使用new关键字创造对象,构造器  Person zy = new Person();
    - 对象的属性 zy.name
    - 对象的方法 zy.sleep()
6.类
    静态的属性   属性
    动态的行为   方法


 */

对象的创建分析

  • 使用 new 关键字创建对象
  • 使用 new 关键字创建的时候,除了分配内存内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
  • 类中构造器也称为构造方法,是在进行创建对象的时候必须要调用的。
  • 构造器必须掌握
  • 特点
  • 必须和类的名字相同
  • 必须没有返回类型,也不能写void
  • 作用
  • new 本质在调用构造方法
  • 初始化对象的值
  • 注意点
  • 定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造器
package OOP.Demo02;

public class Application {
    public static void main(String[] args) {

        //实例化了一个对象
        Person person = new Person("zy");

        System.out.println(person.name);
    }
}
package OOP.Demo02;

//java --> class
public class Person {

    //一个类即使什么都不屑,也会存在一个方法
    //显示的定义构造器
    String name;

    //实例化初始值
    //1.使用new关键字,本质实在调用构造器
    //2.构造器用来初始化值
    public Person(){

    }

    //有参构造,一旦定义了有参构造,无参构造就必须显示定义
    public Person(String name){
        this.name = name;
    }

    //快捷键   alt + insert (+ fn)
}
  • 内存分析

java 面向对象编程与设计 java面向对象编程开发_java

package OOP.Demo03;

public class Application {
    public static void main(String[] args) {
        Pet dog = new Pet();
        dog.name = "wangcai";
        dog.age = 3;
        dog.shout();

        System.out.println(dog.name);
        System.out.println(dog.age);
    }
}
package OOP.Demo03;

public class Pet {
    String name;
    int age;

    public void shout(){
        System.out.println("叫了一声");
    }
}

面对对象三大特性

  • 封装
  • 该露的露,该藏的藏
  • 追求“高内聚,低耦合”。高内聚就是类的内部数据擦欧总细节自己完成,不允许外部干涉;低耦合就是仅暴露少量的方法给外部使用
  • 封装(数据的隐藏)
  • 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏
  • 记住这句话就够了:属性私有,get/set
package OOP.Demo04;

/*
1.提高程序的安全性,保护数据
2.隐藏代码的实际细节
3.统一接口
4.系统的可维护性增加
 */

public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();

        s1.setName("zy");

        System.out.println(s1.getName());

        s1.setAge(99);
        System.out.println(s1.getAge());

    }
}
package OOP.Demo04;

//类
public class Student {

    //属性私有
    //名字
    private  String name;
    //学号
    private int id;
    //性别
    private char sex;
    //年龄
    private int age;

    //学习()

    //睡觉()

    //提供一些可以操作这个属性的方法
    //提供一些public 的 getter/setter方法

    //get 获得这个数据
    public String getName(){
        return this.name;
    }

    //set 给这个数据设置值
    public void setName(String name){
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 120 || age < 0){
            this.age = 3;
        }else{
            this.age = age;
        }
    }
}
  • 继承
  • Java中,所有类,都默认直接或者间接继承Object
  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模
  • extends 的意思是“扩展”,子类是父类的扩展
  • Java中类只有单继承,没有多继承
  • 继承是类和类之间的一种关系。除此之外,类与类之间的关系还有依赖、组合、聚合等
  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示
  • 子类和父类之间,从意义上讲应该具有“is a”的关系
package OOP.Demo05;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();
        System.out.println(student.getMoney());
    }
}
package OOP.Demo05;

public class Person {

    private int money = 10000;

    public void say(){
         System.out.println("说了一句话");
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
package OOP.Demo05;

public class Student extends Person{

}
package OOP.Demo05;

public class Teacher extends Person{

}
  • object类
  • super
  • super调用父类的构造方法,必须在构造方法的第一个
  • super必须只能出现在子类方法或构造方法中
  • suoper和this不能同时调用构造方法
  • 与this区别
  • 代表对象不同
  • this 本身调用者的这个对象
  • super 代表父类对象的应用
  • 前提
  • this 没有继承也可以使用
  • super 只能在继承条件下才可以使用
  • 构造方法
  • this() 本类的构造
  • super() 父类的构造
package OOP.Demo06;

public class Application {
    public static void main(String[] args) {

        Student student = new Student();

        System.out.println("====================");
        student.test("blue");

        System.out.println("======================");
        student.test1();

    }
}
package OOP.Demo06;

public class Person {

    Person(){
        System.out.println("Person无参构造");
    }

    protected String name = "zzzy";

    public void print(){
        System.out.println("Person");
    }
}
package OOP.Demo06;

public class Student extends Person{

    private String name = "zy";

    public Student(){
        //隐藏代码,调用了父类的无参构造
        super();//调用父类构造器,必须放在子类的第一行
        System.out.println("Student无参构造");
    }

    public void print(){
        System.out.println("Student");
    }

    public void test(String name){
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);
    }

    public void test1(){
        print();
        this.print();
        super.print();
    }

}
package OOP.Demo06;

public class Teacher extends Person{
}
  • 方法重写:需要有继承关系,子类重写父类方法
  • 方法名,参数列表必须相同,方法一致,方法体不同
  • 修饰符:范围可以扩大但不能缩小 public > protected > default > private
  • 抛出的异常:范围可以被缩小但不能扩大: ClassNotFoundException --> Exception
package OOP.Demo07;

public class Application {

    //静态的方法与非静态的方法区别很大
    //静态方法:方法的调用只和左边,定义的数据类型有关
    //非静态:  重写
    public static void main(String[] args) {


        A a = new A();
        a.test();//A

        //父类的引用指向了子类
        B b = new A();//子类重写了父类的方法
        b.test();//B
    }
}
package OOP.Demo07;

public class A extends B{

    //Override  重写
    @Override   //有功能的注释
    public void test(){
        System.out.println("A -> test()");
    }
}
package OOP.Demo07;

//重写都是方法的重写,与属性无关
public class B {
    public  void test(){
        System.out.println("B -> test()");
    }
}
  • 多态
  • 动态编译 类型:可扩展性
  • 同一方法可以根据发送对象的不同而采用多种不同的行为方式
  • 一个对象的实际类型是确定的,但可以只想对象的引用的类型很有限
  • 多态存在的条件
  • 有继承关系
  • 子类重写
  • 父类引用指向子类对象
  • 注意
  • 父类和子类有关系 类型转换异常 ClassCastException
  • 多态是方法的多态,属性没有多态性
  • 存在条件:继承关系,方法需要重写
  • 不可重写
  • private方法
  • final 常量
  • static 静态方法,属于类,它不属于实例
  • 父类引用指向子类对象
Father f1 = new Son();
package OOP.Demo08;

public class Application {
    public static void main(String[] args) {

        //一个对象的实际类型是确定的
//        new Student();
//        new Person();

        //指向的引用类型不确定    父类的引用指向子类
        //Studnet 能调用的方法都是自己的或者继承父类的
        Student s1 = new Student();
        //Person 父类型,可以指向子类,但是不能调用子类独有的方法
        Person s2 = new Student();
        Object s3 = new Student();

        s2.run();//子类重写父类方法,执行子类的方法
        s1.run();

        System.out.println("=====================");

        //对象能执行哪些方法,主要看对象左边的类型,与右边关系不大
        s1.eat();
//        s2.eat();
        ((Student) s2).eat();

    }
}
package OOP.Demo08;

public class Person {

    public void run(){
        System.out.println("run");
    }
}
package OOP.Demo08;

public class Student extends Person{

    @Override
    public void run() {
        System.out.println("son");
    }

    public  void eat(){
        System.out.println("eat");
    }

}
  • instanceof (引用类型)类型转换
  • 父类引用指向子类的对象
  • 把子类转换为父类,向上转型
  • 把父类转换为子类,向下转型 强制转换
  • 方便方法的调用,减少重复的代码
package OOP.Demo09;

public class Application {

    public static void main(String[] args) {

        //Object > String
        //Object > Person > Teacher
        //Object > Person > Student
        Object object = new Student();

        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

        System.out.println("=============================");
        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);//编译错误

        System.out.println("=============================");
        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);//编译错误
//        System.out.println(person instanceof String);//编译错误

        System.out.println("============================");

        //高                     低
        Person person1 = new Student();

        //student 将这个对象转换为Student 类型,我们就可以使用Student类的方法了
        //高转低   强制转换
        ((Student) person1).go();

        //低转高   直接转
        //子类转换为父类,可能丢失自己的一些方法
        Student student1 = new Student();
        Person person2 = student1;


    }
}
package OOP.Demo09;

public class Person {
    public void rum(){
        System.out.println("runs");
    }
}
package OOP.Demo09;

public class Student extends Person{
    public void go(){
        System.out.println("go");
    }
}
package OOP.Demo09;

public class Teacher extends Person{
}

static详解

package OOP.Demo10;

//Static
public class Student {

    private static int age;//静态的变量  多线程
    private double score;//非静态的变量

    public void run(){
        go();
    }

    public static void go(){

    }

    public static void main(String[] args) {

        Student s1 = new Student();
        System.out.println(Student.age);
//        System.out.println(Student.score);
        System.out.println(s1.age);
        System.out.println(s1.score);

        System.out.println("===========================");
        new Student().run();
        Student.go();
        go();

    }

}
package OOP.Demo10;

//运行顺序如下1,2,3
public class Person {

    //2.一般用于赋初始值
    {
        System.out.println("匿名代码块");
    }

    //1.只执行一次
    static {
        System.out.println("静态代码块");
    }

    public Person(){
        System.out.println("构造方法");
    }

    //3.
    public static void main(String[] args) {
        Person person1 = new Person();

        System.out.println("=============================");
        Person person2 = new Person();


    }

}
package OOP.Demo10;

//	静态导入包/导入别的包的静态方法
import static java.lang.Math.random;
import static java.lang.Math.PI;

public class Test {
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}

抽象类和接口

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

//abstract 抽象类  类   extends 单继承     接口可以多继承
public abstract class Action {
    //约束    有人帮我们实现
    //abstract      抽象方法,只有方法名字,没有方法的实现
    public abstract void doSomething();
}
package OOP.Demo11;

public class A extends Action{
    @Override
    public void doSomething() {

    }
}
  • 接口
  • 普通类:只有具体实现
  • 抽象类:具体实现和规范(抽象方法)都有
  • 接口:只有规范
  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…,则必须能…”的思想。
  • 接口的本质是契约
  • OO的精髓,是对对象的抽象,最能体现这一点的就是接口
  • 声明类的关键字是class,声明接口的关键字是interface0
  • 作用
  • 约束
  • 定义一些方法,不同的人实现
  • public abstract
  • public static final
  • 接口不能被实例化,接口没有构造方法
  • implements可以实现多个接口
  • 必须重写接口中的方法
package OOP.Demo12;

//抽象类: extend
//类 可以实现接口 implements 接口
//实现了接口的类,就需要重写接口中的方法
//利用接口实现多继承
public class UserServiceImpl implements UserService,TImeService{
    @Override
    public void time() {

    }

    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }
}
package OOP.Demo12;

//interface 定义的关键字,接口都需要实现类
public interface UserService {

    //常量    public static final
    int AGE = 99;

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

public interface TImeService {
    void time();
}

内部类

  • 内部类就是在一个类的内部在定义一个类
  • A类中定义一个B类,那么B类相应A类来说就称为内部类,而A类相对于B类来说就是外部类。
  • 成员内部类
  • 静态内部类
  • 局部内部类
  • 匿名内部类
package OOP.Demo13;

public class Applications {

    public static void main(String[] args) {
        Outer outer = new Outer();

        //通过外部类来实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.in();
        inner.getId();
    }
}
package OOP.Demo13;

public class Outer {

    private int id = 10;
    public void out(){
        System.out.println("这是外部类的方法");
    }

    //成员内部类     若加上statc 便是静态内部类
    public class Inner{
        public void in(){
            System.out.println("这是内部类的方法");
        }

        //获得外部类的私有属性
        public void getId(){
            System.out.println(id);
        }
    }

    //局部内部类
    public void method(){
        class B{

        }
    }

}

//一个java类中可以有多个class类,但只能有一个public class类
class A{
    public static void main(String[] args) {

    }
}
package OOP.Demo13;

public class Test {
    public static void main(String[] args) {
        //匿名内部类
        //没有名字初始化类,不用将实例保存在变量中
        new Apple().eat();

        new UserService(){
            @Override
            public void hello() {

            }
        };
    }
}

class Apple{
    public void eat(){
        System.out.println("1");
    }
}

interface UserService{
    void hello();
}