什么是封装?我看到过这样一个例子:
我要用洗衣机洗衣服,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内 部的结构吗?有必要碰电动机吗?有必要了解如何通电的吗?
如果是对于面向过程来说,这些你都得知道。“吾生也有涯,而知也无涯”,面向对象的封装与庄子的思想遥相呼应:用有限的时间去做更适合的事情。
面对过程是软件开发的先驱者,但其局限性不能满足当今的主流市场需求。
封装的核心思想是隐藏实现,暴露接口。
封装的目的:
修饰符 | 权限范围
public | 本类,子类,本包,外部包
protected | 本类,子类,本包
default | 本类,子类
private | 本类
继承主要目的是实现代码复用。
特性:
构造器的继承问题
static修饰符的继承问题
子类是不会继承父类被static修饰的方法和变量,但是可以调用。
super 与 this 关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
final关键字
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:
子类对象实例化过程
new出一个子类对象的时候,必须先new出一个父类对象。子类在调用构造方法时,会先调用父类的构造方法。(默认)
如果不写构造方法,编译器默认加上一个无参构造器。如果写了构造器,编译器不会添加。
如果写了有参构造器,子类就必须调用父类的构造方法。super(参数)。
如果同时有有参和无参构造器,那么会默认调用无参。也可以自定义调用有参。
提高了代码的通用性。
多态分为编译时多态(方法重载)和运行时多态(方法重写)。
重写指子类重写父类的方法,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private或者final 则子类就不能重写该方法。
重载发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同。
在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能调用子类的方法。
package java.lang;
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}
Object的主要组成:
==与equals的区别
== 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型 就是比较内存地址。
equals的话,,如果该方法没有被重写过默认等同于==;
但是很多类默认重写了:(比如String)
装箱:基本数据类型--->包装类
拆箱:包装类--->基本数据类型
//装箱
Integer t = new Integer(500);
//float to Float
Float f = new Float(“4.56”);
//拆箱
Integer x = 3;
int i = x.intValue();
//int to String
String str = String.valueOf(1);
//String to int
int x = Integer.parseInt(str1) ;
//包装类 to String
Integer x = 8;
String str = x.toString();
or
String str = Integer.toString(3);
在Java类中,可用static修饰属性、方法、代码块、内部类。
被修饰后的成员具备以下特点:
在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
static修饰的方法不能被重写
static的应用:单例模式——静态内部类
class StaticClassInner {
private StaticClassInner() {}
/*
使用静态内部类,实现了延迟加载
调用getInstance()方法时,才会加载StaticClassInnerInstance。
通过JVM类加载线程安全的机制,避免了线程不安全。
*/
private static class StaticClassInnerInstance {
private static final StaticClassInner INSTANCE = new StaticClassInner();
}
public static StaticClassInner getInstance() {
return StaticClassInnerInstance.INSTANCE;
}
}
public class Operation
{
public static void main(String[] args) {
StaticClassInner doubleCheck1 = StaticClassInner.getInstance();
StaticClassInner doubleCheck2 = StaticClassInner.getInstance();
System.out.println(doubleCheck1.hashCode());
System.out.println(doubleCheck2.hashCode());
}
}
对类或对象进行初始化。
代码块可分为静态代码块和非静态代码块。(有无static修饰)
静态代码块:用static修饰的代码块
非静态代码块:没有static修饰的代码块
定义Java类的语法格式:先写extends,后写implements
class SubClass extends SuperClass implements InterfaceA{ }
接口和抽象类之间的对比
在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者 称为外部类。
Inner class的名字不能与包含它的外部类类名相同;
成员内部类(static成员内部类和非static成员内部类)
class Outer {
private int s;
public class Inner {
public void mb() {
s = 100;
System.out.println("在内部类Inner中s=" + s);
}
}
public void ma() {
Inner i = new Inner();
i.mb();
} }
public class InnerTest {
public static void main(String args[]) {
Outer o = new Outer();
o.ma();
} }
局部内部类(不谈修饰符)
class 外部类{
方法(){
class 局部内部类{ }
}
{class 局部内部类
{ }
}
}
匿名内部类
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一 个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或 实现一个类。
匿名内部类的特点
interface A{
public abstract void fun1();
}
public class Outer{
public static void main(String[] args) {
new Outer().callInner(new A(){
//接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
public void fun1() {
System.out.println(“implement for fun1");
}
});// 两步写成一步了
}
public void callInner(A a) {
a.fun1();
}
}
异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。
(开发过程中的语法错误和逻辑错误不是异常)
Java程序在执行过程中所发生的异常事件可分为两类:
异常处理机制一: try-catch-finally
在编写程序时,经常要在可能出现错误的地方加上检测的代码, 如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据 而是字符等。过多的if-else分支会导致程序的代码加长、臃肿, 可读性差。因此采用异常处理机制。
异常处理是通过try-catch-finally语句实现的。
try{
...... //可能产生异常的代码
}
catch( ExceptionName1 e ){
...... //当产生ExceptionName1型异常时的处置措施
}
catch( ExceptionName2 e ){
...... //当产生ExceptionName2型异常时的处置措施
}
[ finally{
...... //无论是否发生异常,都无条件执行的语句
} ]
异常处理机制二: throws