基本数据类型 对应的包装类 * byte Byte * boolean Boolean * char Character * int Integer * long Long * short Short * float Float * double Double
// 1.自动装箱: // 基本类型自动封装到对应的包装类对象中,如: Integer i = 100; // 本质上编译器编译时添加了: Integer i = new Integer(100); // 2.自动拆箱: // 包装类对象自动转换成对应的基本类型数据,如: int a = new Integer(100); // 本质上编译器编译时添加了: int a = new Integer(100).intValue();
同一个类 同一个包 子类 全部类 private √ default √ √ protected √ √ √ public √ √ √ √ 封装要点: * 1.属性成员通常使用 private * 2.提供相应的 getter/setter 方法来访问相关属性,这些方法一般是 public(注意:boolean 变量的 getter 方法是用: is 开头!) * 3.只用于本类的辅助性方法用 private,但愿其余类可以调用的方法使用 public
1. static 用于声明静态方法和静态成员 注意:在 static 方法中可直接访问 static 声明的成员;不能够直接访问非 static 的成员,只能先实例化对象才能进行访问! 2. final 一般用于声明常量 注意:不能继承用 final 修饰的类,不能对用 final 定义的方法进行重写! 3. this 调用本类中的属性和方法 注意:this 不建议用于调用本类中用 static 声明的属性和方法上; this();必须位于重载的构造方法中的第一句,来调用无参构造器! 4. super 是对直接父类对象的引用。能够经过 super 来访问父类中被子类覆盖的方法和属性。任何类的构造函数中,Java 默认都会调用 super(); 注意:super(); 必须位于子类构造方法的第一句! 5. instanceof 用于判断一个对象是不是指定类的一个实例,用法:boolean ins = object instanceof class; 注意:object 必须是对象的引用,不能是基本数据类型
构造器,又称构造方法,是一种特殊的方法 * 格式:public + 类名(){} * 1.经过 new 关键字调用 * 2.构造方法名必须和类名一致! * 3.做用:构造该类的对象,常常用来初始化对象的属性 * 4.不能定义返回值类型,也不能在里面使用 return
* 5.构造方法也能够重载
抽象类 abstract,为全部子类提供一个通用的模板 * 要点: * 1.含有抽象方法的类必定是抽象类,因此在定义时必须定义成抽象类! * 2.抽象类不能实例化,即不能用 new 来实例化抽象类 * 3.抽象类只能用来被继承 extends * 4.抽象方法必须经过子类重写 * 5.抽象类中能够包含属性,非抽象方法,构造方法等
* 6.声明抽象方法不可写出大括号 public abstract class Animal { public static final int MIN_VALUE = 100; private String name; public abstract void fun(); public Animal(){ System.out.println("建立一个动物对象"); } public void hello(){ System.out.println("hello,abstract!"); } }
接口 interface * 接口比抽象类更加的“抽象”,意义在于规范设计和实现代码分离 * 接口中只有:常量,抽象方法! * 接口能被子类实现 implements * 普通类只能单继承,可是接口支持多继承! * 不能实例化,即不能用 new 来实例化 public interface MyInterface { // 接口中只有:常量,抽象方法 // 定义常量:public static final ...,可省略 String MAX_GREAD = "BOSS"; int MAX_SPEED = 100; // 定义方法:public abstract ...,可省略 void test01(); int test02(int a, int b); } // 接口支持多继承 interface Interface03 extends Interface01, Interface02 ...{ }
1. 多态性是 OOP 中的一个重要特性,主要是用来实现动态联编的。换句话说,就是程序最终状态只有在执行过程当中才能被决定,而不是在编译期间就决定,这对于大型系统来讲能提升系统的灵活性和扩展性 2. 多态的存在要有 3 个必要条件: a.要有继承 b.要有方法重写 c.父类引用指向子类对象 public class Fruit { private String color; public void name(){ System.out.println("fruit"); } } public class Apple extends Fruit{ // 继承 @Override public void name(){ // 重写父类方法 System.out.println("apple"); } } public class Test{ public static void main(String[] args) { Fruit f = new Apple(); // 父类引用指向子类对象 f.name(); } }
// 运行结果:apple
内部类分为静态内部类和动态内部类 * 1.内部类使用的场合:因为内部类提供了更好的封装性,而且能够很方便的访问外部类的属性。因此,一般在只为所在外部类提供服务的状况下优先使用内部类 * 2.内部类被当成其所在外部类的内部属性 * 3.动态内部类能够直接访问外部类的私有属性和方法;静态内部类只能直接访问外部类的静态属性和静态方法,访问非静态成员须要实例化外部类对象 * 4.内部类不容许除了其所在的外部类之外的其余类直接访问 public class TestInnerclass { public static void main(String[] args) { // 其余类访问动态内部类,先实例化外部类对象,再实例化动态内部类 World w = new World(); Human human = w.new Human(); human.hello(); // 其余类访问静态内部类,直接实例化静态内部类对象 Animal animal = new World.Animal(); animal.hello(); } }
public class World{ private String hi = "hello"; public void say(String name){ System.out.println("hello,"+name); } // 动态内部类 class Human{ String name = "man"; void hello(){ //动态内部类直接访问所在外部类的私有属性和方法 System.out.println(hi); say(name); } } // 静态内部类 static class Animal{ String name = "animal"; void hello(){ //静态内部类访问所在外部类的非静态属性和非静态方法必须先实例化外部类对象 World w = new World(); System.out.println(w.hi); w.say(name); } } }
匿名内部类,一种特殊的内部类,是一个没有显式的名字的内部类 * 1.匿名内部类会隐式的继承一个类或者实现一个接口 * 2.经常使用于在多线程的实现上,由于要实现多线程必须继承 Thread 类或是实现 Runnable 接口 * 3.匿名内部类只能访问 final 修饰的所在外部类变量及方法参数 * 4.接口自己是不能够经过 new 来实例化的,其实匿名内部类是对接口的实现类的实例化 // Thread 类的匿名内部类 public class Demo { public static void main(String[] args) { Thread t = new Thread() { public void run() { for (int i = 1; i <= 6; i++) { System.out.print(i + " "); } } }; t.start(); } } // Runnable 接口的匿名内部类 public class Demo { public static void main(String[] args) { Runnable r = new Runnable() { public void run() { for (int i = 1; i <= 6; i++) { System.out.print(i + " "); } } }; Thread t = new Thread(r); t.start(); } } //运行结果:1 2 3 4 5 6
1. JDK 中定义了不少异常类,全部的异常对象都是派生于 Throwable 类的一个实例,若是内置的异常类不能知足须要,还能够建立本身的异常类 * Throwable * / \ * Error Exception * / / \ * Unchecked Exception Checked Exception Runtime Exception * | * Unchecked Exception 2. 使用异常机制建议: * 1.只在异常状况下使用异常机制,避免使用异常处理代替错误处理,这样会下降程序的清晰性,而且效率低 * 2.应该将整个任务包装在一个 try 语句中,不要进行小颗粒的异常处理,即一个 try 语句能够伴随多个 catch,不要一个 catch 一个 try * 3.异常每每在高层处理 3. Checked exception 异常的处理方法之一:捕获异常处理,try{...}catch(Exception e){e.printStackTrace();}finally{...} * “亲自处理” * * 1.try 语句指定代码就是一次捕获并处理的范围 * 2.每一个 try 语句能够伴随一个或多个 catch 语句,用于处理可能产生的不一样类型异常 * 3.当异常处理的代码执行后,是不会回到 try 语句去执行还没有执行的代码 * * 4.catch 经常使用的方法: * e.printStackTrace();// 用来跟踪异常事件发生时堆栈的内容 * e.getMessage();// 只显示产生异常的缘由,但不显示异常的类名 * e.toString();// 显示异常的缘由和异常的类名 * 这些方法均继承自 Throwable 类 * * 5.catch 捕获异常的顺序:若是异常类之间有继承关系,在顺序安排上需注意: * 越是顶层的类,越放在下面,即越是父类,越放下面 * 如:IOException 是 FileNotFoundException 的父类,若是父类在前面是不会去 catch 子类异常 * 再否则就直接把多余的 catch 省掉 * * 6.finally 指定段的语句,不论是否发生异常,都必须执行! * 一般经过 finally 来“关闭程序块已打开的资源”,好比:关闭IO流、释放数据库链接等 * * 7.执行顺序:try,catch,return ——> 执行 finally * 8.由执行顺序可知:不要在 finally 中使用 return 语句,由于会覆盖掉 try 语句中的存在的 return 语句 4. Checked exception 异常的处理方法之二:声明异常,throws
* “谁调我,谁处理” * * 1.当 Checked exception 产生时,不必定要马上处理它,能够把异常 throws 出去 * 2.当一个方法出现多个 Checked exception,就必须在方法首部列出全部异常,之间用逗号隔开 * * 3.@Override 方法重写时声明异常的规则: * 1.父类方法没有声明异常,子类方法也不能声明异常; * 2.子类方法不可抛出父类方法抛出异常类的父类或更上层类; * 3.子类方法抛出的 异常类型的数目 不能够比父类方法抛出的还多(指不一样异常类型个数) 5. Checked exception 异常的处理方法之三:手动抛出异常,throw * 对于一个已经存在的异常类,手动抛出异常对象过程以下: * 1.找到一个合适的异常类 * 2.建立一个该类的对象 * 3.将异常对象抛出 File f = new File("C:/a.txt"); if(!f.exists){ try{ throw new FileNotFoundException("File can't be found!"); }catch(FileNotFoundException e){ e.printStackTrace(); } } 6. 自定义异常处理 * 1.遇到标准异常类都没法充分描述的异常时能够建立本身的异常类 * 2.从 Exception 类或者它的子类派生一个子类便可 * 3.习惯上,定义的异常类应该包含2个构造器: “无参构造器” 和 “带有详细信息的构造器” public class MyException extends Exception{ //无参构造器 public MyException(){ } //带有详细信息的构造器 public MyException(String message){ super(message); } }