代码
public class Test01 { //定义常量 final static int num = 10; final static Dog dog = new Dog("泰迪","棕黄色"); public static void main(String[] args) { fun(num ); //fun(dog); System.out.println("main"+dog); } public static void fun( ) { dog.setColor("黑色"); //dog = new Dog(); System.out.println("fun"+dog); } public static void fun( int num ) { num++; System.out.println(num); } } class Dog { private String type; private String color; public Dog() { } public Dog(String type, String color) { super(); this.type = type; this.color = color; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override public String toString() { return "Dog [type=" + type + ", color=" + color + "]"; } }代码
public class Test02 { final static int num = (int)(Math.random()*33); static { System.out.println("我是静态代码块"); } public static void main(String[] args) { System.out.println(Test02.num); } } public class Test03 { public static void main(String[] args) { System.out.println(Test02.num); } }先加载静态内容 -> 先执行静态代码块 由于父子关系 所以子类加载之前需要先加载父类
执行的父类的初始化块和欧构造器
准备执行子类的构造器 (先执行初始化块 子类构造器中有一个super)
顺序 父类的静态代码块 子类的静态代码块 父类的初始化块 父类的构造器 子类的初始化块 子类的构造器
代码
public class Test04 { public static void main(String[] args) { new S2().m(); } } class F{ static { System.out.println("F static"); } { System.out.println("F init"); } public F() { System.out.println("F construct"); } } class S1 extends F{ static { System.out.println("S1 static"); } { System.out.println("S1 init"); } public S1() { System.out.println("S1 construct"); } } class S2 extends F{ static { System.out.println("S2 static"); } { System.out.println("S2 init"); } public S2() { System.out.println("S2 construct"); } public void m() { new S1(); } } 运行结果: F static S2 static F init F construct S2 init S2 construct S1 static F init F construct S1 init S1 construct1: 父类中定义的方法不需要具体的实现步骤 子类都不按照父类的做 2: 父类中定义这个方法的目的是告诉子类 一定要保证存在该方法
对于类的要求: 1:父类中不需要定义方法的实现步骤 2:子类必须要重写
抽象类: 包含了抽象方法的的类称之为抽象类。 被abstract修饰的类称之为抽象了
抽象方法: 只要方法的声明,没有方法体。 通过abstract修饰的方法称之为抽象方法
抽象类和抽象方法的关系: 有抽象方法的一定是抽象类; 抽象类不一定有抽象方法,也可以有普通的方法。
为什么需要抽象类? 避免子类的随意设计 提高了代码可读性 提高了子类的健壮性
代码
public class Test01 { } abstract class Person{ public abstract void eat() ; } class Chinese extends Person{ public void eat() { } } class En{ public void eat() { } }代码
public class Test02 { public static void main(String[] args) { // 实例化抽象类 //Father f = new Father(); Son s = new Son(); } } abstract class Father{ public Father() { System.out.println("我是抽象类的构造器"); } public abstract void study(); //public abstract void work(); } class Son extends Father{ public Son() { } public void study() { } }代码
/* * 喝茶 烧水 冲泡 干了 * 喝咖啡 烧水 搅拌 干了 * */ public class Test03 { public static void main(String[] args) { /* * Tea t = new Tea(); t.flow(); * * Caf c = new Caf(); c.flow(); */ Water w1 = new Tea(); w1.flow(); } } abstract class Water{ private void fireWater() { System.out.println("咕噜咕噜咕噜"); } public abstract void pp() ; private void drink() { System.out.println("墩儿~墩儿~墩儿~墩儿~"); } public void flow() { fireWater(); pp(); drink(); } } class Tea extends Water{ public void pp() { System.out.println("冲泡"); } } class Caf extends Water{ public void pp() { System.out.println("搅拌"); } }(final与abstract是对立的)
final修饰的变量称之为最终常量 在程序运行期间其值不可发生改变final修饰的类不可以被继承:太监类final修饰的方法不可以被重写tips: 工具类一般不需要子类 工具方法一般不需要重写,但final在实际应用中较少
代码
public class Test01 { public static void main(String[] args) { String str = "991010010110"; } } /* final */ class Person{ public final void study() { System.out.println("必须早上5点起床"); } } class Student extends Person{ public void study() { System.out.println("这谁顶得住"); } }接口: 接口是一个规范 是一套标准 比抽象了还抽象
接口如何定义: 学习接口和学习类是一样的
接口定义:
1.修饰符 interface 接口名{} 2.接口中的变量都是公开的 静态的最终常量值 默认情况下变量都是public static final修饰 3.接口中可以定义静态方法(不建议1.8) 4.接口中定义的对象方法都是抽象方法 接口中的方法默认就是通过abstract修饰的 5.接口中的默认方法从1.8之后才开始被使用 允许在接口中定义default方法 而且存在方法体代码
public class Test01 { public static void main(String[] args) { } } interface Fly{ int SPEED = 10; default void method() { } public static void fun1() { } public abstract void fun2() ; }修饰符 class 类名 extends 父类 implements 接口
接口深入:
1、类和接口直接通过implements 发生关系 类实现接口 2、类必须要实现接口中的所有抽象方法 3、一个类可以实现多个接口 类名 implements 接口1,接口2。。。。。 4、一个类实现了接口之后 要将当前接口以及接口的父接口中的所有抽象方法全部重写 5、接口可以多继承 6、接口无法实例化 7、接口没有构造器 8、接口中也可以使用多态
代码
public class Test03 { public static void main(String[] args) { Fly f = new SuperMan();//接口变量指向实现类对象 f.fly(); } } interface Fly extends Comparator,Serializable{ /* * public Fly() { * * } */ public void fly(); //public void method(); } class SuperMan implements Fly/* , Comparator */{ public void fly() { System.out.println("飒······"); } public int compare(Object o1, Object o2) { // TODO Auto-generated method stub return 0; } }Tips:
接口就是一套规则,用来定义具体要做哪些事情,但是所有事情的具体实现都会延迟到实现类中完成。接口只需要定义has-a的关系,如果你是什么,则你具备了什么能力。equals方法就是用来比较两个对象是否相等的,默认Object的equals方法比较是两个对象的地址。 java.lang.NullPointerException 空指针异常 对象为null
ClassCastException 类型转换异常null可以强转为任意类型 null也可以是任意类型(不能强转为基本数据类型)代码
public class Test01 { public static void main(String[] args) { //创建两个user对象 User u1 = new User("zhangsan","123"); User u2 = new User("zhangsan","123"); System.out.println(u1==u2);//== 比较两个对象的地址 System.out.println(u1.equals(u2)); String str = "哎~~~"; System.out.println(u1.equals(str)); User u3 = new User(); System.out.println(u3.equals(null)); } } class User{ private String name; private String pwd; public User() { // TODO Auto-generated constructor stub } public User(String name, String pwd) { super(); this.name = name; this.pwd = pwd; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public String toString() { return "User [name=" + name + ", pwd=" + pwd + "]"; } @Override public boolean equals(Object obj) {//Object obj = u2; Object obj = "哎~~~"; if(!(obj instanceof User)) { return false; } //将obj强转为user User other = (User)obj; if(this.name!=null&&this.pwd!=null) { //比较用户名和密码 if(this.name.equals(other.name)&&this.pwd.equals(other.pwd)) { return true; } } return false; } }