什么是封装?我看到过这样一个例子:
我要用洗衣机洗衣服,只需要按一下开关和洗涤模式就可以了。有必要了解洗衣机内 部的结构吗?有必要碰电动机吗?有必要了解如何通电的吗?
如果是对于面向过程来说,这些你都得知道。“吾生也有涯,而知也无涯”,面向对象的封装与庄子的思想遥相呼应:用有限的时间去做更适合的事情。
面对过程是软件开发的先驱者,但其局限性不能满足当今的主流市场需求。
面对过程注重微观,每一步都亲力亲为;面对对象注重宏观,更加偏向于整体的流程。
性能:面对过程执行效率更高。Java是编译成字节码给JVM运行,而面向过程直接编译成机器码执行
复用性:面对对象的封装,继承极大的扩展了代码的复用性
封装的核心思想是 隐藏实现,暴露接口 。
封装的目的:
public | 本类,子类,本包,外部包
protected | 本类,子类,本包
default | 本类,子类
private | 本类
继承主要目的是实现代码复用。
子类是不会继承父类被static修饰的方法和变量,但是可以调用。
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
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的话,,如果该方法没有被重写过默认等同于==;
但是很多类默认重写了:(比如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的应用:单例模式——静态内部类
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修饰)
定义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程序在执行过程中所发生的异常事件可分为两类:
在编写程序时,经常要在可能出现错误的地方加上检测的代码, 如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据 而是字符等。过多的if-else分支会导致程序的代码加长、臃肿, 可读性差。因此采用异常处理机制。
Java程序的执行过程中如出现异常,会生成一个异常类对象, 该异常对象将被提交给Java运行时系统,这个过程称为抛出 (throw)异常。
如果一个方法内抛出异常,该异常对象会被抛给调用者方法中处 理。如果异常没有在调用者方法中处理,它继续被抛给这个调用 方法的上层方法。这个过程将一直继续下去,直到异常被处理。 这一过程称为捕(catch)异常。
程序员通常只能处理Exception,而对Error无能为力。
try{
...... //可能产生异常的代码
}
catch( ExceptionName1 e ){
...... //当产生ExceptionName1型异常时的处置措施
}
catch( ExceptionName2 e ){
...... //当产生ExceptionName2型异常时的处置措施
}
[ finally{
...... //无论是否发生异常, 都无条件执行的语句
} ]
如果抛出的异常是IOException等类型的非运行时异常,则必须捕获,否则 编译错误。也就是说,我们必须处理 编译时异常 ,将异常进行捕捉,转化为 运行时异常 。