面向对象(4)

面向对象(3)

本章重点:

在这里插入图片描述

1·封装:

1.对于本类而言 安全
2.对外而言 调用简单

本类同包子类同包无关类异包子类异包无关类
publicYYYYY
protecredYYYYN
默认的YYYNN
privateYNNNN

2·继承:

1)定义:

就是将多个类中的共性再一次抽取为一个父类。通俗而言就是子承父业。

子类 extends 父类

2)注意:

(1)继承在一定程度上提高了代码的复用率,但复用性的提高是有限的;
(2)Java只支持单一继承;
(3)父类的功能不满足子类的需求 子类可以重写
(4)子类拥有父类的所有属性和方法(根据修饰确定是否能够全部继承)
(5)通过super()调用父类的构造器
(6)Object是所有类的父类
(7)super. 调用父类中的内容(不能省略 调用时父类中的内容和子类同名 调用父类中的内容)

3·单例模式:

一个类只能产生一个实例对象

编写方式:

1:构造器私有

2:对外提供获取对象的方法

3:声明一个static的成员变量 类加载的时候创建当前单例对象

4:在获取对象方法中返回成员变量的值

饿汉式例题分析:
public class Danli {
	//做不到延迟加载
	public static Danli dan=new Danli();
	private Danli(){
		
	}
	public static Danli getDanli(){
		return dan;
	}

}
测试类:
package com.mage.danli;

public class TestDan {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Danli d=Danli.getDanli();
		System.out.println(d);

	}

}

懒汉式例题分析:
package com.mage.danli;
public class Lazy {
	static Lazy l=null;
private Lazy(){
	
}
public static Lazy getLazy(){
	if(l==null){
		l= new Lazy();
	}
	return l;
}
}
测试类:
package com.mage.danli;

public class TestLazy {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Lazy n=Lazy.getLazy();
		System.out.println(n);
	}

}


对比分析:

饿汉式

(1) 缺点: 不能做到延迟加载

(2) 优点: 天然线程安全

懒汉式

(1) 缺点: 线程不够安全

(2) 优点: 能做到延迟加载

4·多态:

构成多态的前提条件:

  • 1:继承关系
    
  • 2:父类变量指向了子类对象
    
  • 3:一定要有方法的重写
    

5·类型转换:

自动:
父类 = 子类对象
强制:
子类型 = (子类型) 父类变量
父类变量中实际存储的类型

6·final:

(1)final修饰的变量称之为最终常量 在程序运行期间其值不可发生改变

(2)final修饰的类不可以被继承:最终类

(3)final修饰的方法不可以被重写

(4)final 修饰的引用类型的变量 只保证地址不变 对象中的内容可以发生改变。

7·类的加载顺序:

1.先加载静态内容 -> 先执行静态代码块 由于父子关系 所以子类加载之前需要先加载父类

2.执行父类的初始化块和构造器

3.准备执行子类的构造器 (先执行初始化块 子类构造器中有一个super)

  • 父类的静态代码块
  • 子类的静态代码块
  • 父类的初始化块
  • 父类的构造器
  • 子类的初始化块
  • 子类的构造器4
例题1分析:
public class Test04 {
	public static void main(String[] args) {
		new S2().m();
	}
}

class F{
	static {
		System.out.println("F static");
	}
	{
		System.out.println("F init");
	}
	public F() {
		System.out.println("F construct");
	}
}

class S1 extends F{
	static {
		System.out.println("S1 static");
	}
	{
		System.out.println("S1 init");
	}
	public S1() {
		System.out.println("S1 construct");
	}
}

class S2 extends F{
	static {
		System.out.println("S2 static");
	}
	{
		System.out.println("S2 init");
	}
	public S2() {
		System.out.println("S2 construct");
	}
	public void m() {
		new S1();
	}
}

运行结果:

在这里插入图片描述

内存图分析:

在这里插入图片描述

注意:

1.静态成员常量不会导致类加载

2.静态成员常量的值在加载前无法确定 那么会导致类加载

例题2分析:

在这里插入图片描述

package com.mage.oop;

public class Test03 {
	public static void main(String[] args) {
		
		System.out.println(Test02.num);
		
	}
}	

执行结果分析:

静态成员常量的值在加载前无法确定 那么会导致类加载
在这里插入图片描述
在这里插入图片描述

package com.mage.oop;

public class Test03 {
	public static void main(String[] args) {
		
		System.out.println(Test02.num);
		
	}
}	

执行结果分析:

.静态成员常量不会导致类加载
在这里插入图片描述

8·抽象类:

1.学习抽象类:

​ 1: 父类中定义的方法不需要具体的实现步骤 子类都不按照父类的做

​ 2: 父类中定义这个方法的目的是告诉子类 一定要保证存在该方法

2.对于类的要求:

​ 1:父类中不需要定义方法的实现步骤

​ 2:子类必须要重写所有的抽象方法

3.抽象类:

​ 1:包含了抽象方法的的类称之为抽象类。

​ 2:被abstract修饰的类称之为抽象了

​ 3:抽象类既可以定义抽象方法也可以定义普通方法

​ 4:抽象类可以存在构造器但是不能实例化,抽象类中的构造器是给 子类准备的。

​ 5:抽象类就是用来被继承的,抽象方法就是用来被重写的。

4.抽象方法:

​ 1:只要方法的声明,没有方法体。 通过abstract修饰的方法称之为抽象方法

5.为什么需要抽象类?

​ 1:避免子类的随意设计 提高了代码可读性 提高了子类的健壮性

​ 2:父类中不需要定义方法的实现步骤

​ 3:子类必须要重写

代码3分析:

在这里插入图片描述
在这里插入图片描述

9·模板方法:

将上下文中的一些不会变化的内容保留下来 在父类中实现,并且定义整个程序的执行流程,将核心的业务逻辑或者是算法逻辑延迟到子类中去实现。

代码4分析:
public class Test03 {
	public static void main(String[] args) {
		
		Water w1 = new Tea();
		w1.flow();		
	}
}
abstract class Water{
	private void fireWater() {
		System.out.println("咕噜咕噜咕噜");
	}
	
	public abstract void pp() ;
	
	private void drink() {
		System.out.println("墩儿~墩儿~墩儿~墩儿~");
	}
	
	public void flow() {
		fireWater();
		pp();
		drink();
	}
}
class Tea extends Water{
	
	public void pp() {
		System.out.println("冲泡");
	}
	
}
class Caf extends Water{
	
	
	public void pp() {
		System.out.println("搅拌");
	}
	
	
}

分析:

在这里插入图片描述

10·接口:

简单定义:
  • 修饰符 interface 接口名{}
  • 变量都是公开的 静态的最终常量值 默认情况下变量都是public static final修饰
  • 在1.8以后可以定义静态方法和默认方法(最好别这样)
  • 接口中定义的对象方法都是抽象方法 接口中的方法默认就是通过abstract修饰的
代码5分析:

在这里插入图片描述

深入理解:

定义

接口就是一套规则,用来定义具体要做哪些事情,但是所有事情的具体实现都会延迟到实现类中完成。接口只需要定义has-a的关系,如果你是什么,则你具备了什么能力


使用方式**:

修饰符 class 类名 extends 父类 implements 接口


注意:

1、 类和接口直接通过implements 发生关系 类实现接口

2、类必须要实现接口中的所有抽象方法

3、一个类可以实现多个接口 类名 implements 接口1,接口

4、一个类实现了接口之后 要将当前接口以及接口的父接口中的所有抽象方法全部重写

5、接口可以多继承

6、接口无法实例化

7、接口没有构造器

8、接口中也可以使用多态

代码6分析:

在这里插入图片描述

equals方法:

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

Tips

null可以强转为任意类型 null也可以是任意类型。

package com.mage.duotai;

public class login { 
	public static void main(String[] args) { 
	//创建两个user对象 
	User u1 = new User("damengmeng","123");
	User u2 = new User("dameng","123"); 
	System.out.println(u1==u2);
	//== 比较两个对象的地址 
	System.out.println(u1.equals(u2)); 
	String str = "nihai"; 
	System.out.println(u1.equals(str));
	User u3 = new User(); 
	System.out.println(u3.equals(null)); 
	} 
}
class User{ 
	private String name;
	private String pwd;
	public User() { 
	// TODO Auto-generated constructor stub 
	}
public User(String name, String pwd) { 
	super(); 
	this.name = name; 
	this.pwd = pwd; 
	}
public String getName() {
	return name;
	}
public void setName(String name) {
	this.name = name;
	}
public String getPwd() {
	return pwd;
}
 

public void setPwd(String pwd) { 
	this.pwd = pwd; 
	}
public String toString() {
	return "User [name=" + name + ", pwd=" + pwd + "]"; 
	}
@Override 
public boolean equals(Object obj) {
	
	if(!(obj instanceof User)) {
		return false; 
		}
	User other = (User)obj; 
	if(this.name!=null&&this.pwd!=null) { 
		if(this.name.equals(other.name)&&this.pwd.equals(other.pwd)) { 
			return true; 
			} 
		}return false; 
		} 

}


运行结果图:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值