【JAVA笔记】5_Java面向对象


一、初识面向对象

  • 面向过程:步骤清晰,每一步做什么;适合简单问题(线性思维)
  • 面向对象:分类思维,再对某一分类下的细节进行面向对象的操作;适合复杂及多人协作问题
  • 对于复杂事务,宏观上使用面向对象分析整个系统,围观操作时使用面向过程思维处理
  • 属性+方法=类
  • 对象是通过引用来操作的:栈---->堆(地址)

1.面向对象编程(OOP)

本质:以类的方式组织代码,以对象的方式封装数据
抽象

  • 认识论角度:先有对象后有类,对象时具体事物,类是对对象的抽象
  • 代码运行角度:先有类后有对象,类是对象的模板

2.三大特征

封装、继承、多态

3.属性

字段Field 成员变量
默认初始化:
数字:0 0.0
char:u0000
boolean:false
引用:null

修饰符 属性类型 属性名 = 属性值
如:人是类,张三是对象,其性别、年龄等静态特征是属性,说话等对象执行的操作是方法

二、类与对象的创建

1.类与对象的关系

  • 类是一种抽象的数据类型,是对某一类事物整体描述/定义,但不能代表某一个具体事物
  • 类用于描述/定义某一类具体事物应具备的特点和行为
  • 对象是抽象概念的具体实例,如张三是人的一个具体实例

2.创建与初始化对象

  • 使用new关键字创建对象
  • new除了分配内存空间外,还会给创建好的对象进行默认的初始化及对类中构造器的调用
  • 类中的构造器也称为构造方法,是在进行创建对象时必须要调用的
  • 构造器特点:1.必须和类的名字相同;2.必须没有返回类型,也不能写void
//一个项目应该只存在一个main方法
public class Application {
    public static void main(String[] args) {
        //类:抽象的,需要实例化
        //类实例化后会返回一个自己的对象
        //student对象就是一个Student类的具体实例
        Student xiaoming = new Student();
        Student xiaohong = new Student();

        System.out.println(xiaoming.name); //null

        xiaoming.name = "小明";
        System.out.println(xiaoming.name); //小明

    }
}
//学生类
public class Student {
    //属性:字段
    String name;
    int age;

    //方法
    public void study(){
        System.out.println(this.name+"在学习");
    }
}
  • 一个类即使什么也不写,它也会存在一个方法

三、构造器详解

  • 实例化初始值
  • 使用new关键字,本质是在调用构造器
  • 有参构造:一旦定义有参构造,无参必须显式定义
public class Person {
    //一个类即使什么也不写,它也会存在一个方法
    String name;

    //实例化初始值
    public Person(){
        this.name = "Ted";
    }
}

参考教程:
https://m.php.cn/article/419827.html

四、创建对象内存分析

在这里插入图片描述

五、封装

高内聚,低耦合
类的内部数据操作细节不允许外部干涉;
仅暴露少量的方法给外部使用
属性私有,get/set
alt+insert快捷键

package oop.demo3;
public class Student {
    //属性私有,外部对象不能直接使用
    private String name;//名字
    private int id;//学号
    private char sex;//性别

    //提供一些可以操作这个属性的方法
    //public的get、set方法

    //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;
    }
}
package oop;
import oop.demo3.Student;
public class Application {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.getName();
        s1.setName("Ted");
        System.out.println(s1.getName());
        s1.getId();
        s1.setId(24);
        System.out.println(s1.getId());

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

六、继承

  • 继承的本质是对某一批类的抽象
  • 只有单继承
  • 继承是类之间的关系(还有依赖、组合、聚和……)
  • 子类(派生类)父类(基类)
  • 子类继承父类,使用关键字extends表示
  • 子类 is a 父类
  • private无法被继承
  • 先调用父类的无参构造(super();)
  • 注:在java中,所有的类都默认继承Object

1.super

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

super和this的区别:

  • this:本身调用这个对象;没有继承也可以使用;本类的构造
  • super:代表父类对象的应用;只能在继承条件才能使用;父类的构造

2.方法重写Override

·重写都是方法的重写,与属性无关
·父类的引用指向了子类
·静态方法:方法的调用只和定义的数据类型有关(即左边)
·非静态方法下子类重写了父类的方法,执行子类的方法

  • 重写需要有继承关系,子类重写父类的方法:
  • 方法名必须相同
  • 参数列表必须相同
  • 修饰符范围可以扩大但不能缩小:public>protected>default>private
  • 抛出的异常范围可以被缩小但不能扩大:ClassNotFoundException --> Exception(大)
    重写,子类的方法和父类必须一致,方法体不同
  • 为什么需要重写:
    父类的功能,子类不一定需要或者不一定满足

七、多态

-动态编译
同一方法可以根据发送对象的不同而采用多种不同的行为方式

  • 一个对象的实际类型是确定的,但是可以指向对象的引用的类型很多
  • 多态存在的条件:有继承关系子类重写父类方法父类引用指向子类对象(Father f1 = new Son()😉
  • 注:多态是方法的多态,属性没有多态性
  • instanceof :判断一个对象是什么类型,判断两个类是否存在父子关系

Object object = new Student();
object instanceof Student //object指向的实际类是不是Student的子类

(类型转换) 引用类型

//Student类是Person类的子类
//可以指向的引用类型不确定:父类的引用指向子类
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
  • 子类能调用的方法都是自己的或者继承父类的
  • 父类可以指向子类,但是不能调用子类独有的方法
  • 子类转换为父类,可能丢失自己本来的一些方法
    高转低 强制转换:
Person obj = new Student();
//将该对象转换为Student类型,就可以使用Student类型的方法
Student student = (Student) obj;
student.go();

八、static关键字

public class Person{
	//2.一般用于赋初始值
	{
		System.out.println("匿名代码块");
	}
	//1.只执行一次
	static {
		System.out.println("静态代码块");
	}
	public Person(){
		System.out.println("构造方法");
	}
	public static void main(String[] args){
		Person person = new Person();
	}
	/*
	输出:
	静态代码块
	匿名代码块
	构造方法
	*/
//静态导入包
import static java.Math.random;

· 类前面加final就不能继承

九、抽象类

//abstract 抽象类
public abstract class Action {
	//抽象方法,只有方法名字,没有方法实现
	public abstract void doSomething();

}
//继承了抽象类的子类,必须实现抽象类的所有方法
public class A extends Action{
	public void doSomething() {
	
	}
}

抽象类不能new,只能靠子类去实现
抽象类中可以写普通方法
抽象方法必须在抽象类中

十、接口

  • 自己无法写方法,只有规范
  • 本质是契约
  • 声明接口的关键字:interface
  • 接口中所有定义都是抽象的public abstract
  • 实现的类需要重写接口中的方法
package oop.demo5;

//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.demo5;

//类可以实现接口:implements 接口
//实现了接口中的类,就需要重写接口中的方法
public class UserServiceImp1 implements UserService{
    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }
}

  • 利用接口实现多继承:public class UserServiceImp1 implements UserService,TimeService{}
  • 接口的作用:
  • 约束
  • 定义了一些方法,让不同人实现
  • public abstract
  • public static final
  • 接口不能被实例化,因为接口中没有构造方法
  • implements 可以实现多个接口
  • 必须要重写接口中的方法

十一、内部类

  • 在一个类的内部再定义一个类
  • 内部类可以获得外部类的私有属性和私有方法
  • 一个java类中可以有多个class类,但是只能有一个public class

1.成员内部类

  • 定义在外部类的成员位置上
  • 内部类在外部使用时,需要通过外部类信息才能完成实例化
  • 内部类可以直接访问外部类的成员;如果出现同名属性或者方法,优先访问内部类中定义的
  • 可以使用 外部类.this.成员 的方式,访问外部类中同名的信息(成员属性和成员方法)
  • 外部类访问内部类信息,需要通过内部类实例,无法直接访问
package oop.demo6;

public class Outer {
    private int id = 10;
    public void out(){
        System.out.println("这是外部类方法");
    }
    public class Inner{
        public void in(){
            System.out.println("这是内部类方法");
        }
        //获得外部类的私有属性
        public void getID(){
            System.out.println(id);
        }
    }
package oop;
//import oop.demo3.Student;
//import oop.demo4.Student;
import oop.demo6.Outer;
public class Application {
    public static void main(String[] args) {
        //new
        Outer outer = new Outer();
        //通过外部类实例化内部类
        Outer.Inner inner = outer.new Inner();
        inner.in(); //这是内部类方法
        inner.getID(); //10
    }
}

注:
获取成员内部类对象实例方法:

  1. 通过外部类对象创建内部类实例,即

new 外部类().new 内部类() 或 外部类对象.new 内部类()

  1. 通过外部类定义的成员方法获取,即

外部类对象.get方法()

2.静态内部类

  • static修饰
  • 获取静态内部类对象实例: new 外部类名.静态类();
  • 静态内部类中,只能直接访问外部类的静态成员,如果需要调用非静态成员,可以通过对象实例
public class Outer {
    private int id = 10;
    
    //定义静态内部类
    public static class Inner{
        public void in(){
            System.out.println("这是内部类方法");
        }
        //获得外部类的私有属性
        public void getID(){
            System.out.println(id);
        }
     public static void main(String[] args) {
        //调用静态内部类
        Outer.StaticInner staticInner = new StaticInner();
        staticInner.getID();
    }
}

3.方法内部类(局部内部类)

  • 当一个类只需要在某个方法中使用了某个特定的类时使用
  • 不能使用任何访问修饰符,不能使用static修饰
  • 类中不能包含静态成员,但可以包含final、abstract修饰的成员
public class Outer {
    private static int a;
    private int b ;
    public void partClassTest(final int c){
        final int d =1;
        //在partCLassTest方法中定义一个局部内部类PastClass
        class PastClass{
            public void print(){
                System.out.println(c);
            }
        }
    }
}

4.匿名内部类

  • 没有名字的类
  • 通过匿名内部类简化对于抽象类和接口实现的操作
  • 不用将实例保存到变量中

参考资料:https://www.jianshu.com/p/79f6d2aca1d8


网课来源

【狂神说JAVA】https://www.kuangstudy.com/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值