java基础知识(返璞归真)——chapter1(面向对象)

说到java,不得不说java的一个梗。
没有女朋友就new一个girl friend;
Gril mygirlfriend = new person();

一.面向对象特征------封装性
为什么要引入封装性
首先程序设计追求“高内聚,低耦合”
①高内聚:类内部数据操作细节自己完成,不允许外部干涉
②低耦合:仅对外暴露少量的方法用于使用。

简单的来说,隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的维护性,可扩展性。

1)封装性思想具体的代码提现:
①private私有化
②不对外暴露私有方法
③单例模式:在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。所谓单例模式,就是保证类在内存中只有一个对象
2)说到单例模式说两种常见实现方式:
具体实现需求:
①将构造器方法私有化,使其不能在类的外部通过new关键字实例化该类对象
②在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型
③定义一个静态方法返回这个唯一对象

懒汉式和饿汉式
懒汉式和饿汉式的区别是创建单例对象的时间不同
一个是懒加载,只有在对象需要用的时候采取创建这个对象。
一个是在内存加载的时候已经创建了这个对象
① 懒汉式线程不安全
缺点:不支持多线程,因为没有加锁

class Singleton{
	private static Singleton instance = null;//不建立对象
	private Singleton(){}
	
	public static Singleton getInstance(){
		if(instance == null){//先判断是否为空
			instance = new Singleton();
		}
		return instance;
	}
}

② 懒汉式线程安全
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。

class Singleton{
	private static Singleton instance = null;
	private Singleton(){}
	
	public static synchronized Singleton getInstance(){
		if(instance == null){
			instance = new Singleton();
		}
		return instance;
	}
}

③ 饿汉式

class Singleton{
	private static Singleton instance = new Singleton();
	private Singleton(){}
	
	public static Singleton getInstance(){
		return instance;
	}
}

二.面向对象特征------继承性
2.1子类继承父类特点:
① 子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私的结构。只因为封装性的影响,使得子类不能直接调用父类的结构而已。
② 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。
在这里插入图片描述

class A extends B{}
 *    A:子类、派生类、subclass
 *    B:父类、超类、基类、superclass

一个类可以被多个子类继承。
Java中类的单继承性:一个类只能有一个父类,俗话说只能有一个爸爸,多个儿子
子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
子类继承父类以后,就获取了直接父类以及所间接父类中声明的属性和方法
在这里插入图片描述2.2 Object类
① Object类是所有java类的父类
② 如果类中未声明extends关键字指明父类,则默认父类为Object类
③ Object类中的功能就具通用性
属性:无
方法:equals()/toString()/getClass/hashCode()/clone()/finalize()/wait()/notify()/notifyAll()
④Object只声明了一个空参的构造器
⑤数组也作为Oject类的子类出现,可以调用Object类中声明的方法
使用说明:
① Object类中定义的equals()==作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
② 像
String,Data,File,包装类
等都重写了Object类中的equals方法,重写以后比较的不是两个引用的地址是否相同,而是比较两个对象的实体内容是否相同。
自定义类若要比较两个对象的**“实体内容**”是否相同。那么,我们就需要对Object类中的equals()进行重写。
重写的原则:比较两个对象的实体内容是否相同
基本数据类型用==,引用数据类型用equals
2.3子类对象实例化全过程
① 从结果上看:创建子类的对象,在堆空间中,就回家再父类中所声明的属性
② 从过程上看:通过子类构造器创建子类对象,一定会直接或间接调用其父类的构造器,进而调用父类的父类构造器,直至调用了java.langl.Object类中的空参的构造器为止。
在这里插入图片描述
③虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即new的子类对象。
三、面向对象------多态性
3.1 多态性的理解
可以理解为一个事物的多种形态。比如数据库的连接方式,我们定义好了数据库的连接,也规定了连接时的步骤,但是我们并不知道用户采用什么数据库,在没有多态以前我们只能针对不同的数据库写不同的连接方法,而有了多态以后我们只需要定义好数据库的类并书写好连接方法,让所有的数据库继承书数据库类并重写数据库连接方法。

这样我们在调用的时候只需要声明数据库类并指向数据库的子类的方式,(即数据库类的引用指向继承了数据库类的具体实现类的对象)就可以进行数据库连接,而不是需要针对不同的数据库书写不同的连接方式。
3.2 何为多态性
对象的多态性:父类的引用指向子类的对象
编译和运行时的类型不一致,产生了多态

Person p = new Man();
Object obj = new Date();

3.3多态性的使用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
总结:编译看左边,运行看右边。

3.4多态使用总结
使用前提:①需要存在继承或者实现关系②有方法的重写
成员方法:
①编译时,要查看引用变量所声明的类中是否有所调用的方法
②运行时,调用实际new的对象所属的类中的重写方法

3.5 关于向上转型和向下转型
向上转型:多态
为什么要使用向下转型?"
有了对象的多态性后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,而子类中特有点属性和方法不能调用,如何才能调用子类特有的属性和方法?使用向下转型

Person p = new Man();

Man m1=(Man)p;//向下转型

使用时注意点
1.使用强转,可能出现ClassCastException的异常。
2.为了避免出现ClassCastException的异常,我们在向下转型之前,先进性instanceof的判断,一旦返回true,就进行向下转型,如果返回false,不能进行向下转型。
3.只有对象A是B的子类实例化对象或者在下层的子类,才能向下转型

p instanceof Man//左边是变量名,右边是类的类型

在这里插入图片描述
面试题:
1.谈谈你对多态性的理解?
这是java面向对象的特征之一----多态性,为什么会出现多态?
以我个人的理解来说,举个例子,在没有出现多态以前,面对不同的数据库需要不同的连接方法,那么这对代码复用性不高,而多态的出现,只需要将不同的数据库继承于数据库类,并且当想要调用不同数据库的时候只需要将数据库类声明的引用指向子类数据库,并且调用里面重写的连接方法或者不同数据库所对应的不同方法。
抽象类和接口的使用肯定体现了多态性,因为接口和抽象类是不能够实例化的
多态的前提条件是该子类继承父类或者实现该类,并且重写父类中的方法
那么对于底层而言,多态虽然是以父类类型声明的引用,但其实在内存当中已经加载了子类的成员变量和成员方法,这就是为什么出现向上转型和向下转型,向上转型就是多态,那么如果需要使用子类特有的属性和方法,则需要通过向下转型,强制转换成子类即可
2.为什么说多态是运行时行为?

class Base {
	int count = 10;

	public void display() {
		System.out.println(this.count);
	}
}

class Sub extends Base {
	int count = 20;

	public void display() {
		System.out.println(this.count);
	}
}

public class FieldMethodTest {
	public static void main(String[] args) {
		Sub s = new Sub();
		System.out.println(s.count);//20
		s.display();//20
		
		Base b = s;//多态性
		//==:对于引用数据类型来讲,比较的是两个引用数据类型变量的地址值是否相同
		System.out.println(b == s);//true
		System.out.println(b.count);//10
		b.display();//20
	}
}

感觉有点博弈论的味道
首先方法覆盖才具有多态性,那如果没有为什么要继承呢?
编译时期调用的是父类中所定义好的方法,计算机在运行时期先去检测子类是否有覆盖父类中的方法,覆盖了则调用子类中的方法,若没覆盖则调用父类中的这个方法,若父类中也没有这个方法,则编译就已经直接报错了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

破晓以胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值