面向对象

面向对象

面向对象和面向过程不是相对的,而是伴生关系。
面向对象和面向过程的对比:

面对对象:宏观上把控整个事务的完成度以及事务走向。是对象帮我们处理具体的问题,而对象是如何做的,和调用者无关,调用者只需要负责结果即可。
调用的复杂度降低。底层具体的实现思路还是过程式的。
面向过程:微观上更精细化的处理具体问题

  • 类:分门别类。抽象的概念 。
  • 对象:将类中所有抽象的内容进行了具象化 。 现实生活中真实存在的。
  • 类和对象:类是对于对象的抽象,抽象就是抽取像的部分对象就是对于类的具象化的体现。

问题:
先有类还是先有对象?
如果是编写过程: 先有类 再有对象
如果是构建过程: 先有对象,将对象的共性抽离出来,外在、内在->类

** 面向对象内存示意图 **
在这里插入图片描述
static的用法

static叫做 静态的 共享的 所属于类的 类被加载的时候会优先加载静态内容
static修饰的内容只有一份,被所有的对象以及类共享,对于static修饰的内容改变,也被所有对象可见
static修饰的内容两种调用方式:
通过类名直接点 类名(建议)
通过对象调用对象

如何在一个静态内容中调用非静态内容:

  • 1:在非静态内容中加static
  • 2:创建非静态内容的所属对象 通过对象调用

在非静态内容中调用静态方法:

  • 可以直接调用,
  • 非静态内容隶属于对象,如果非静态内容能够被调用,对象一定存在,对象存在证明类一定能被加载。 而类被加载,静态内容一定被加载。

什么时候类会被加载?

  • 1:调用当前类中的静态方法
  • 2:创建当前类的实例对象的时候

构造器

在类中用来创建对象的那个方法称之为构造器,构造函数,构造方法

构造器是一个特殊方法:

  1. 方法名称和类名相同
  2. 无返回值
  3. 允许方法重载
  4. 默认存在无参构造器,如果于当前类显性写出构造器,则无参自动消失

构造器的作用就是来创建对象的

  1. 构造器只能通过new 来调用

tips:当给一个类中的成员变量的;类型声明为基本数据类型之后,导致基本数据类型存在默认值。
未赋值的情况下存在值,后续的逻辑可能存在问题。

this的用法

this.
当前对象的——> 谁在调用 代表谁
可省略:
不可省略: 区分同名变量,局部变量和成员变量
this()
构造器之间的互相调用
this()一定要在构造器的首行
在这里插入图片描述
数据类型经过方法

  • 基本数据类型经过方法之后 其值不变。值传递
  • 引用数据类型进过方法之后 其值会变,值传递(地址值)
  • 通过两个变量指向了同一个内存地址,一个对内存进行改变 另一个可见

继承

在这里插入图片描述
继承是java面向对象编程技术的一块基石,它允许创建分等级层次的类。

在Java中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类。

所有Java的类均是由java.lang.Object类继承而来的,所以Object是所有类的祖先类,而除了Object外,所有类必须有一个父类。

通过过extends关键字可以申明一个类是继承另外一个类而来的。

 class A{
	private int a;
	public int b;
	public void fun(){
		System.out.println("hh");
		System.out.println(a);
	}
}
public class B extends A{
	public static void main(String[] args){
			A a=new A();
			B b=new B();
			A c=new B();
			System.out.println(a instanceof A);
			System.out.println(b instanceof B);
			System.out.println(c instanceof A);
			System.out.println(c instanceof B);
		} 
}
输出结果:
true
true
true
true

tips:可以使用 instanceof 运算符来检验Mammal和dog对象是否是Animal类的一个实例
输出一个对象的时候默认情况下会调用当前对象的toString
==比较基本数据类型比较的是值 比较引用类型比较的是地址
equals:用来比较相等的 如果相等返回true 反之返回false
Object中的比较是通过 == 比较的

通过使用关键字extends,子类可以继承父类的除private属性外所有的属性。

重写(Override)与重载(Overload)

重写(Override)

重写规则
  1. 参数列表必须完全与被重写方法的相同;
  2. 返回类型必须完全与被重写方法的返回类型相同;
  3. 子类方法的访问权限必须大于或等于父类方法的访问权限
  4. 声明为static的方法不能被重写,但是能够被再次声明
  5. 构造方法不能被重写
  6. 必须发生继承关系,子类重写父类

为什么需要重写?

  • 父类的功能不能满足子类的需求。子类在父类的基础上进行了扩展。

如何确定一个方法是重写方法?

  • 在子类的方法上加入@Overried 注解 如果不报错 证明是重写
Super关键字的使用

当需要在子类中调用父类的被重写方法时,要使用super关键字。

super的用法

  • super是指向父类的引用,如果构造方法没有显示调用父类的构造方法,编译器会自动为它加上一个默认的super()方法调用。
  • 当父类中存在其他构造器时,无参构造器不存在,此时如果再子类中没有通过super()显示的指定调用的构造器,会导致程序报错。
  • super()和this()均需放在构造方法内第一行,不能同时调用两个。

实质:this是一个指向本对象的指针, 然而super是一个Java关键字。

重载(Overload)

方法的重载

封装

什么是封装?

将抽部分抽象的方法的实作细节部份包装、隐藏起来的方法。

为什么要封装?

是一份保护,防止该类的代码和数据被外部类定义的代码随意访问,提升了代码的健壮性

如何封装?

通过修饰变量写一些修饰方法屏蔽部分底层代码的实现逻辑和细节,降低调用者的复杂度。
如果用private修饰的话 一定要保证对外提供get、set方法让外部课件

稍等

单例模式

什么是单例: 一个类只能产生一个实例对象。例如任务管理器

如何编写?

  1. 构造器私有
  2. 对外提供过去对象的方法
  3. 声明一个static的成员变量 类加载的时候创建当前单例对象
  4. 在获取对象方法中返回成员变量的值

饿汉式

缺点: 不能做到延迟加载
优点: 天然线程安全

public class Single {
// 声明一个Single对象
public static Single single = new Single();
//1:将构造器私有
private Single() {
}
/**
* public : 外界一定是通过该方法获取当前类的实例对象 所以对外一定要可见
* static : 外部无法获取到当前类的实例对象 所以只能用static修饰 属于类的 可以通
过类名调用
* 不加static要通过对象调用 对象没有
* 返回值 : 当前类的实例
*
*/
public static Single getInstance() {
return single;
}
public static void add() {
}
}

懒汉式

能够做到延迟加载 但是线程不安全

public class Lazy {
	private static Lazy lazy = null;
	private Lazy() {
	}
	public static Lazy getInstance() {
		if(lazy==null) {
			lazy = new Lazy();
	}
	return lazy;
	}
}

多态

什么是多态?

同一个行为具有多个不同表现形式或形态的能力。

构成多态的前提条件:

  1. 继承关系
  2. 父类变量指向了子类对象
  3. 一定要有方法的重写
public class Test01 {
	public static void main(String[] args) {
/*
* Animal an = new Animal(); an.eat();
* Dog d = new Dog(); d.eat(); d.lookDoor();
*/
		Animal an1 = new Dog();// 父类变量指向了子类对象
		an1.sleep();
		an1.eat();// 编译看左边 运行看右边
		// an1.lookDoor();
	}
}
class Animal{
	public Animal() {
	}
	public void sleep() {
		System.out.println("animal sleep");
	}
	public void eat() {
		System.out.println("animal eat");
	}
}
class Dog extends Animal{
	public Dog() {
	}
	@Override
	public void eat() {
		System.out.println("dog eat");
	}
	public void lookDoor() {
		System.out.println("看门");
	}
}

final

final修饰静态常量进过方法

  • final 修饰的基本数据类型变量 无法进行修改的
  • final 修饰的引用类型的变量 只保证地址不变 对象中的内容可以发生改变

类的加载顺序

先加载静态内容 -> 先执行静态代码块 由于父子关系 所以子类加载之前需要先加载父类
执行的父类的初始化块和欧构造器
准备执行子类的构造器 (先执行初始化块 子类构造器中有一个super)

类型转换

自动转换

  • 父类型 变量名 = 子类对象;【new 子类对象|子类对象的变量】

强制转换

  • 子类型 变量名 = (子类型)父类变量; [事先确定了父类变量中实际存储的对象是什么类型]
    ClassCastException 类型转换异常

抽象类

父类中定义的方法不需要具体的实现步骤 子类都不按照父类的做
父类中定义这个方法的目的是告诉子类 一定要保证存在该方法
对于类的要求:

  1. 父类中不需要定义方法的实现步骤
  2. 子类必须要重写

为什么需要抽象类?
避免子类的随意设计 提高了代码可读性 提高了子类的健壮性

接口

接口定义

  • 修饰符 interface 接口名{}
  • 接口中的变量都是公开的 静态的最终常量值 默认情况下变量都是public static final修饰
  • 接口中可以定义静态方法(不建议1.8)
  • 接口中定义的对象方法都是抽象方法 接口中的方法默认就是通过abstract修饰的
  • 接口中的默认方法从1.8之后才开始被使用 允许在接口中定义default方法 而且存在方法体
    饰符 class 类名 extends 父类 implements 接口

接口深入:

  • 1、 类和接口直接通过implements 发生关系 类实现接口
  • 2、类必须要实现接口中的所有抽象方法
  • 3、一个类可以实现多个接口 类名 implements 接口1,接口2。。。。。
  • 4、一个类实现了接口之后 要将当前接口以及接口的父接口中的所有抽象方法全部重写
  • 5、接口可以多继承
  • 6、接口无法实例化
  • 7、接口没有构造器
  • 8、接口中也可以使用多态

equals方法

equals方法就是用来比较两个对象是否相等的,默认Object的equals方法比较是两个对象的地址。

  • java.lang.NullPointerException 空指针异常 对象为null
  • ClassCastException 类型转换异常
  • null可以强转为任意类型 null也可以是任意类型

内部类

一个类可以在另一个类中声明。这种类型的类称为内部类。

内部类可以继承另一个内部类,顶级类或其封闭类。
内部类中没有静态成员,允许在内部类中有作为编译时常量的静态字段。
每个内部类都被编译成一个单独的类文件。

内部类类型

有三种类型的内部类。内部类的类型取决于位置和声明的方式。

  • 成员内部类
  • 局部内部类
  • 匿名内部类

优点:缩短了变量的生命周期,减少内存的消耗

成员内部类

成员内部类在类中声明的方式与声明成员字段或成员方法相同。
它可以声明为public,private,protected或package-level。
成员内部类的实例可以仅存在于其封闭类的实例内。

局部内部类

一个局部内部类在块中声明。其范围仅限于声明它的块。
由于其范围限于其封闭块,因此其声明不能使用任何访问修饰符
通常,在方法内定义局部内部类。但是,它也可以在静态初始化器,非静态初始化器和构造器中定义。

匿名内部类

匿名内部类没有名称。因为它没有名称,它不能有一个构造函数。
匿名类是一次性类。
new运算符用于创建匿名类的实例。
它后面是现有的接口名称或现有的类名称。
接口名称或类名称不是新创建的匿名类的名称。
如果使用接口名称,则匿名类实现接口。
如果使用类名,则匿名类继承自类。
仅当新运算符后面跟有类名时,才使用。如果新运算符后跟接口名称,则它为空。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值