一周总结
面向对象和面向过程
区别
面向过程:事物比较简单,可以用线性的思维去解决
面向对象:事物比较复杂,使用简单的线性思维无法解决
共同点:事物比较复杂,使用简单的线性思维无法解决
二者相辅相成,并不是对立的。
解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系、方便 我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理
对象和类
对象:是具体的事物 xiaoming xiaohong
类:是对对象的抽象(抽象à抽出象的部分)Person
先有具体的对象,然后抽象各个对象之间象的部分,归纳出类通过类再认识其他对象。
对象和类的关系:
特殊到一般,具体到抽象。
类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
类是用于描述同一类形的对象的一个抽象的概念,类中定义了这一类对象所应具有的静态和动态属性。
JDK提供了很多类供编程人员使用,编程人员也可定义自己的类。
类的构成:属性 field方法 method 构造方法 construtor 代码块 静态代码块 内部类
成员变量和局部变量
声明位置不同 类中 方法中
作用范围不同: 当前类的方法 当前方法
不同的方法中即使有同名的局部变量,没有关系,互不影响,建议相同
内存存放的位置的:栈内存中 堆内存中
成员变量有默认值;局部变量没有默认值
Java中的对象和数组是通过引用对其操作的.
引用可以理解为一种受限的指针
指针是可以进行与整数做加减运算的,两个指针之间也可以进行大小比较运算和相减运算。引用不行,只能进行赋值运算。
引用就是一个变量或对象的别名(引用的本质是一个对象);指针是一个段内存空间的地址(指向存储一个变量值的空间或一个对象的空间)
栈和堆
栈:存放:局部变量
先进后出,自下而上存储
方法执行完毕,自动释放空间
堆:存放new出来的对象
需要垃圾回收器来回收
构造器( constructor 构造方法):一个在创建对象时被自动调用的特殊方法。
构造器作用:创建对象并对对象进行初始化(成员变量)
构造器是一种特殊的方法:
构造器的方法名必须和类名一致!
构造器虽然有返回值,但是不能定义返回类型(返回值的类型肯定是本类),不能在构造器里调用return。
通过new关键字调用!!
如果我们没有定义构造器,则系统会自动定义一个无参的构造方法。如果已定义则编译器不会添加无参数构造方法!
与普通方法一样,构造方法也可以重载
This
this: this表示的是当前对象本身,更准确地说,this代表当前对象的一个引用。
普通方法中使用this:
区分类成员属性和方法的形参.
调用当前对象的其他方法(可以省略)
位置:任意
构造方法中使用this:
使用this来调用其它构造方法
位置:必须是第一条语句
this不能用于static方法,static隶属于类,this指代对象,static先于对象存在。
Static
在类中,用static声明的成员变量为静态成员变量 ,或者叫做: 类属性,类变量.
它为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化,
对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!
可以使用”对象.类属性”来调用。不过,一般都是用“类名.类属性”
static变量置于方法区中!
用static声明的方法为静态方法
不需要对象,就可以调用(类名.方法名)
在调用该方法时,不会将对象的引用传递给它,所以在static方法中不可访问非static的成员。
静态方法不能以任何方式引用this和super关键字
为什么需要package?
为了解决类之间的重名问题。
为了便于管理类:合适的类位于合适的包!
package import
包:作用
导入:import com.bjsxt.oop.*;
静态导入: import static java.lang.Math.PI;
常用的5个包:lang awt net io util
面向对象的三大特征:继承 封装 多态 (抽象)
继承 inheritance
子类 父类
子类可以从父类继承属性和方法
子类可以提供自己单独的属性和方法
Tips
通过继承可以简化类的定义,实现代码的重用
子类继承父类的成员变量和成员方法,但不继承父类的构造方法
java中只有单继承 ,没有像c++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。多继承,就是为了实现代码的复用性,却引入了复杂性,使得系统类之间的关系混乱。
java中的多继承,可以通过接口来实现
如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
方法的重写
在子类中可以根据需要对从基类中继承来的方法进行重写。
重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
重写方法不能使用比被重写方法更严格的访问权限。(由于多态)
封装/隐藏encapsulation
对外隐藏某些属性和方法
对外公开某些属性和方法
多态 polymorphism
为了适应需求的多种变化,使代码变得更加通用!
面向过程只有封装性(功能的封装,而没有数据的封装),没有继承和多态
我们程序设计要追求“高内聚,低耦合”。
高内聚:类的内部数据操作细节自己完成,不允许外部干涉;
低耦合 :仅暴露少量的方法给外部使用。
多态性是OOP中的一个重要特性,主要是用来实现动态联编的,换句话说,就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。这对于大型系统来说能提高系统的灵活性和扩展性。
java中如何实现多态?使用多态的好处?
引用变量的两种类型:
编译时类型(模糊一点,一般是一个父类)
由声明时的类型决定。
运行时类型(运行时,具体是哪个子类就是哪个子类)
由实际对应的对象类型决定。
多态的存在要有3个必要条件:
要有继承,要有方法重写,父类引用指向子类对象
引用数据类型的类型转换
子类转换为父类:自动转换
上转型对象不能操作子类新增的成员变量和方法。
上转型对象可以操作子类继承或重写的成员变量和方法
如果子类重写了父类的某个方法,上转型对象调用该方法时,是调用的重写方法。
父类转换为子类:强制转换
final可以用来修饰变量,方法,类。
修饰变量:变量一旦被初始化便不可改变,相当定义了一常量
修饰方法:final方法是在子类中不能被覆盖的方法
修饰类:final类是无法被任何类继承的。
为什么需要抽象类? 如何定义抽象类?
是一种模版模式。抽象类为所有子类提供了一个通用模版,子类可以在这个模版基础上进行扩展。
通过抽象类,可以避免子类设计的随意性。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
抽象类要点:
抽象方法和抽象类均必须用abstract来修饰。
抽象方法没有方法体,只需要声明不需实现。
有抽象方法的类只能定义能抽象类
相反抽象类里面的方法不一定全是抽象方法,也可能没有抽象方法。
抽象类可以包含属性、方法、构造方法。
抽象类不能实例化,及不能用new来实例化抽象类,只能用来被子类调用。
抽象类只能用来继承。
抽象方法必须被子类实现。抽象类的子类必须覆盖所有的抽象方法才能被实例化,否则 还是抽象类
为什么需要接口?接口和抽象类的区别?
接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。
接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。
接口相关规则
接口中所有方法都是抽象的。
即使没有显式的将接口中的成员用public标示,也是public访问类型的
接口中变量默认用 public static final标示,所以接口中定义的变量就是全局静态常量。
可以定义一个新接口,用extends去继承一个已有的接口
可以定义一个类,用implements去实现一个接口中所有方法。
可以定义一个抽象类,用implements去实现一个接口中部分方法。
|
继承 |
被继承 |
实现 |
被实现 |
接口 |
接口 |
接口 抽象类 普通类 |
无 |
抽象类 普通类 |
抽象类 |
接口 抽象类 普通类 |
抽象类 普通类 |
接口 |
无 |
普通类 |
接口 抽象类 普通类 |
抽象类 普通类 |
接口 |
无 |
内部类
将一个类定义置入另一个类定义中就叫作“内部类”
类中定义的内部类特点
内部类作为外部类的成员,可以直接访问外部类的成员(包括private成员),反之则不行。
内部类做为外部类成员,可声明为private、默认、protected或public。
内部类成员只有在内部类的范围之内是有效的。
用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
编译后生成两个类: OuterClass.class 和OuterClass$InnerClass.class
内部类分类
成员内部类 静态内部类 方法内部类 匿名内部类
单例:通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例
(懒汉,线程不安全):
1. public class Singleton {
1. private static Singleton instance;
2. private Singleton (){}
3.
4. public static Singleton getInstance() {
5. if (instance == null) {
6. instance = new Singleton();
7. }
8. return instance;
9. }
10. }
工厂模式: 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的
public static Pizza getInstance(int i) {
if (i == 1) {
return new Pergen();
} else if (i == 2) {
return new Seafood();
}
return null;
}
成员(成员变量或成员方法)访问权限共有四种:
public 公共的 可以被项目中所有的类访问。(项目可见性)
protected 受保护的 可以被这个类本身访问;同一个包中的所有其他的类访问;被它的子类(同一个包以及不同包中的子类)访问
default/friendly 默认的/友好的(包可见性) 被这个类本身访问;被同一个包中的类访问。
private 私有的 只能被这个类本身访问。(类可见性)
类的访问权限只有两种
public 公共的
可被同一项目中所有的类访问。 (必须与文件名同名)
default/friendly 默认的/友好的
可被同一个包中的类访问。
异常机制
异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
Java的异常处理是通过5个关键字来实现的:try、catch、 finally、throw、throws
捕获异常:try catch finally
Try:执行可能产生异常的代码
catch :捕获异常
Finally:无论是否发生异常,代码总能执行
声明异常:throws 声明方法可能要抛出的各种异常
抛出异常:throw 手动抛出异常
异常分为Checked异常和运行时异常
Checked异常必须捕获或者声明抛出
运行时异常不要求必须捕获或者声明抛出
try-catch-finally中存在return语句的执行顺序
finally块中语句不执行的情况
throw和throws关键字的区别
常用类
public class StringDemo {
public static void main(String[] args) {
String s1 = "Hell0 World";
String s2 = new String();
String s3 = new String("Hello World");
// 根据下标取字符
char c = s1.charAt(10);
System.out.println(c);
// 返回字符串长度
int i = s1.length();
System.out.println(i);
s2 = "Hello World";
// 特殊情况
System.out.println(s1 == s2);
// == 用于做内存地址的比较
System.out.println(s3 == s2);
// 对象内容的比较
System.out.println(s1.equals(s2));
// 忽略大小写进行内容比较
String s4 = new String("HELLO WORLD");
System.out.println(s3.equalsIgnoreCase(s4));
// 返回寻找的字符的下标不存在返回-1
System.out.println(s1.indexOf('0'));
System.out.println(s1.indexOf("l"));
// 返回寻找的字符出现的最后一次的下标不存在返回-1
System.out.println(s1.lastIndexOf("l"));
System.out.println(s1.lastIndexOf("0"));
// 将字符串中所有的l字符替换为a字符
String newS1 = s1.replace('l', 'a');
System.out.println(newS1);
// 将字符串中所有的He字符串换成vv字符串
String newSs = s1.replaceAll("He", "vv");
System.out.println(newSs);
// 判断是否以此开头
boolean b1 = s1.startsWith("He");
System.out.println(b1);
// 是否以此结尾
boolean b2 = s1.endsWith("ld");
System.out.println(b2);
String ns = "我是张三的好朋友";
// 截取字符串(包含开始下标,不包含结束下标)
String nns = ns.substring(2, 4);
System.out.println(nns);
// 从第5个下标截取到最后
String nnns = ns.substring(5);
System.out.println(nnns);
// 全转小写
String ns1 = s1.toLowerCase();
System.out.println(ns1);
// 全转大写
String ns2 = s1.toUpperCase();
System.out.println(ns2);
// 去除前后空格
String t = " a b c ";
System.out.println(t.length());
String nt = t.trim();
System.out.println(nt.length());
System.out.println(s1);
String a = "张三";
String b = "a bc";
String d = a.concat(b);//a+b;
System.out.println(d);
// 检查字符串中是否存在这个字符
boolean contains = b.contains("b");
System.out.println(contains);
// 将字符串转换为byte数组
byte[] bs = a.getBytes();
// 判断字符串是否为空
System.out.println(a.isEmpty());
// 张三#18#男@李四#20#女
String sss = "张三三#18#男@李四#20#女";
String[] sa = sss.split("@");
String[] sa0 = sa[0].split("#");
String[] sa1 = sa[1].split("#");
System.out.println();
String lisi = sss.substring(sss.indexOf("李"), sss.indexOf("四")+1);
System.out.println(lisi);
}
}