面向对象

0. 理解面向对象. 

  • 早期的思想是面向过程, 而现在的面向对象思想是相对于面向过程而言的. 
  • * 面向过程, 强调的功能行为. 面向对象, 将功能封装进对象, 强调具备了功能的对象. 
  • * 面向对象是基于面向过程的. 
  • * 面向过程到面向对象, 是从执行者到指挥者的转变. 
  • Everything is an Object. 


1. 面向对象开发: 其实就是不断的创建对象, 使用对象, 指挥对象做事情. 


2. 面向对象设计: 其实就是管理和维护对象之间的关系. 


3.* 面向对象的特征:

  • 封装(encapsulation): 指隐藏对象的属性和实现细节, 仅对外提供公共访问方式. 
    好处: 将变化隔离; 便于使用; 提高重用性; 提高安全性. 
    封装原则: 将不需要对外提供的内容都隐藏起来; 把属性都隐藏, 提供公共方法对其访问. 
  • 继承(inheritance): 多个类中存在相同属性和行为时,就将这些内容抽取到单独一个类中, 那么多个类无需再定义这些属性和行 为,只要继承单独的那个类即可. 
    好处: 继承的出现提高了代码的复用性. 继承的出现让类与类之间产生了关系, 提供了多态的前提. 
    *
    注意: Java只支持单继承. 但是接口对接口之间不是用实现(implements), 也是用继承(extends), 此时可以多继承. 
  • ** 多态(polymorphism): 可以理解为事物存在的多种体现形态(不只对象有多态性, 函数的重载也是多态性的体现). 
    体现: 父类或者接口的引用指向或者接受自己的子类对象. 
    好处: 多态的出现大大提高程序的扩展性. 
    弊端: 提高了扩展性, 但是只能使用父类的引用访问父类中的成员. 
    作用: 多态的存在提高了程序的扩展性和后期的可维护性. 
    前提: 需要存在继承或者实现关系; 要有覆盖操作. 
    特点:
    (非静态)成员函数: 编译时, 要查看引用变量所属的类中是否有所调用的成员; 运行时, 要查看对象所属的类中是否有所调用的成员. (编译时看左边, 运行时看右边.) 
    * 成员变量: 无论编译和运行, 只看引用变量所属的类(左边). 
    静态成员函数: 无论编译和运行, 只看引用变量所属的类(左边). 


4. 成员变量 VS 局部变量. 

  • 成员变量定义在类中, 在整个类中都可以被访问. 成员变量随着对象的建立而建立, 存在于对象所在的堆内存中.* 成员变量有默认初初始化值. 
  • 局部变量只定义在局部范围内(函数内、语句内等). 局部变量存在于栈内存中, 作用范围结束后, 变量空间自动释放.* 局部变量没有默认初始化值. 

5. 构造代码块. 写在独立{}中的代码. 
  • 作用: 给对象进行初始化. 
  • * 对象一旦建立就执行, 优先于构造函数执行. 
  • 和构造函数的区别: 构造代码块是给所有对象进行统一初始化, 而构造函数是给对应的对象初始化. 


6.* this关键字.

  • 特点: this代表其所在函数所属对象的引用. 换言之, this代表类对象的引用. 
  • 使用情景: 当函数内需要用到调用该函数的对象时, 就用this. 
  • 静态方法中不能写this、super关键字. 


7.* this关键字在构造函数间的调用. (内部名称: this语句). 

class Person
{
	private String name;
	private int age;
	
	Person(String name)
	{
		this.name = name;
	}
	
	Person(String name, int age)
	{
		//this.name = name;
		//this语句. 直接用this调用Person(String name)构造函数. 因为this代表一个对象, 所以this(name)就相当于new Person(name). 
		this(name);			
		this.age = age;
	}
}

8.* this语句只能写在构造器的第一行. super也是. 


9.* super和this的用法几乎相同.this代表本类对象的引用, super代表父类对象的引用. 

super也有super语句(自己起的名字..), 调用父类构造器. 

如果子类中出现非私有的同名成员变量时, 子类要访问本类中的变量, 用this; 子类要访问父类中的同名变量, 用super. 

class Fu
{
	int num = 4;
}

class Zi extends Fu
{
	int num = 5;
	void show()
	{
		System.out.println(this.num);			//this可以省略
		System.out.println(super.num);
	}
}


10. 被static(静态)关键字修饰的成员(成员变量和成员函数).

  • 随着类的加载而加载. 
  • 优先于对象存在. 
  • 被所有对象所共享. 
  • 可以直接被类名调用. 

11. 静态方法中部可以定义this和super关键字, 因为静态方法是类相关的, 没有创建对象(this或super)时就可以使用. 

12. 一个类中如果不定义的话, 有一个默认构造函数, 它的权限与类相同. 

13. 静态代码块. 

static
{
        ...
}
用于对类进行初始化, 随类的加载而执行, 且只执行一次. 


14.* 单例设计模式: 使一个类在内存中只存在一个对象. 

class Single		//饿汉式
{
	private Single(){}
	
	private static Single s = new Single();
	
	public static Single getInstance()
	{
		return s;
	}
}

class Single_2		//懒汉式, 延迟加载.
{
	private Single_2(){}
	
	private static Single_2 s = null;
	
	public static Single_2 getInstance()
	{
		if(s==null)
		{
			synchronized(Single.class)
			{
				if(s==null)
					s = new Single_2();
			}			
		}
		return s;
	}
}

饿汉式, 懒汉式. 

懒汉式线程不安全, 用synchronized可以解决但是效率变低. 

*建议使用懒汉式. 


15. 覆盖: 

  • 子类覆盖父类, 必须保证子类权限大于等于父类权限, 才能覆盖, 否则编译失败. 
  • 静态只能覆盖静态. 

16.  ** 在对子类对象进行初始化时, 父类的构造函数也会运行, 因为子类的构造函数默认第一行有一条隐式的语句super().
super(): 会访问父类中空参数的构造函数. 而且子类中所有的构造函数默认第一行都是super(). 


17.** 为什么子类一定要访问父类中的构造函数? 
答: 因为父类中的数据子类可以直接获取. 而父类中的数据可能是经过父类构造函数初始化的, 所以在子类使用前必须要经过父类指定构造函数的操作. 


18.** 子类必须调用父类的构造方法, 因为父类中的数据子类可以直接获取, 当子类对象初始化时, 如果父类中没有空参数的构造函数时, 子类的所有构造函数必须通过this或者super语句指定要访问的构造函数. (子类的所有的构造函数, 默认都会访问父类中空参数的构造函数, 如果父类没空参的构造函数, 则要手动通过super或者this指定要访问的构造函数). 


19. final修饰的作为常量, 书写规范: 所有字母都大写, 由多个单词组成时, 单词间用_连接. 


20. 局部内部类只能访问该局部被final修饰的局部变量. 


21. 抽象类: java中可以定义没有方法体的方法, 该方法的具体实现由子类完成, 该方法抽象方法. 包含抽象方法的类就是抽象类. 


22. 抽象类可以有构造函数, 但是不能被实例化(即使是没有抽象方法的抽象函数). 


23.* 模板设计模式: 在定义功能时, 功能的一部分是确定的, 但是有一部分是不去定的. 而确定的部分要使用不确定的部分, 这是就将不确定的部分暴露出去, 由该类的子类去实现. 

class GetTime					//没有用模板设计模式
{
	public void getTime()
	{
		long start = System.currentTimeMillis();
		
		for(int x=0; x<1000; x++)
		{
			System.out.print(x);
		}
		
		long end = System.currentTimeMillis();
		
		System.out.println("毫秒: " + (end-start));
	}
}

abstract class GetTime_2				//模板设计模式. 
{
	public final void getTime()				//该类的功能, 不希望被重写, 所以final.
	{
		long start = System.currentTimeMillis();
		
		runcode();
		
		long end = System.currentTimeMillis();
		
		System.out.println("毫秒: " + (end-start));
	}
	
	public abstract void runcode();		//作为模板, 子类可以通过重写这个方法来获取相应功能. 
}

24. 接口(interface)中的成员修饰符是固定的(可以省略). 

  • * 成员变量: public static final
  • 成员函数: public abstract

25. 接口中的所有成员都是public权限的. 

26. 接口与接口之间可以有继承关系, 且可以是多继承. 

27. java.lang.Object使所有对象的直接或者间接父类. 


28. 内部类: 将一个类定义在另一个类里面, 里面那个类就叫内部类. 


29. 内部类的访问特点: 

  • 内部类可以直接访问外部类中的成员,包括私有成员。
  • 而外部类要访问内部类中的成员必须要建立内部类的对象。

30. 内部类可以定义在成员的位置上, 也可以在局部位置上. 当定义在局部位置上时, 内部类可以直接访问外部类中的成员.* 同时可以访问所在局部中的局部变量,但必须是被final修饰的. 

31. 匿名内部类: 就是内部类的简化写法. 
前提是: 这个内部类要继承或者实现一个外部类或者接口. 

32. 异常(Exception): 就是程序在运行是出现的不正常状况(出现的问题). 
  • 对于严重的, 通过错误(Error)类进行描述; 非严重的, 用异常(Exception)类描述. 
  • 对于Error一般不编写针对性的代码对其进行处理; 而对Exception可以使用针对性的处理方式进行处理. 
  • Error和Exception有共性(不正常情况的信息、引发原因等), 对其抽象为Throwable类. 

33.* Finally代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)关闭虚拟机.  ------->小括号中的数字用来表示退出时的状态, 可以是别的. 

34. 如何自定义异常信息呢?
答: 因为父类中已经把异常信息的操作都完成了, 所以子类只要在构造时, 将异常信息通过super()语句传递给父类, 就可以直接通过getMessage方法获取自定义的异常信息了. 

35. Exception分两种: 
  • 编译时被检测的异常 . 
  • 编译时不被检测的异常(运行时异常. RuntimeException以及其子类). 

36.* RuntimeException: Exception中的一个特殊的子类异常. 如果在函数内抛出该异常, 函数上可以不用声明, 编译一样通过; 如果在函数上声明了该异常, 调用者可以不用进行处理, 一样可以通过. (也可以处理. )
因为: 当该异常发生时, 希望程序停止. 因为在运行时, 出现了无法继续运算的情况, 希望停止程序后, 对代码进行修正. 

37.* 异常细节: 
  • 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。
  • 如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常。

38.* 四种访问权限.

 


39. import用来导包中的类, 不导包中的包. 


40. Jar包的操作. 通过jar.exe工具对jar的操作. 

  • 创建jar包:jar -cvf mypack.jar packa packb
  • 查看jar包:jar -tvf mypack.jar [>定向文件]
  • 解压缩:jar -xvf mypack.jar
  • 自定义jar包的清单文件:jar –cvfm mypack.jar mf.txt packa packb



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值