• Java面向对象理解_代码块_继承_多态_抽象_接口


    面线对象:

    /*
    成员变量和局部变量的区别?
    A:在类中的位置不同
    成员变量:在类中方法外
    局部变量:在方法定义中或者方法声明上
    B:在内存中的位置不同
    成员变量:在堆内存
    局部变量:在栈内存
    C:生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
    D:初始化值不同
    成员变量:有默认初始化值
    局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
     
    注意事项:
    局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
    */
    class Varialbe {
    //成员变量
    //int num = 10;
    int num; //0
     
    public void show() {
    //int num2 = 20; //局部变量
    //可能尚未初始化变量num2
    //int num2; //没有默认值
    int num2 = 20;
    System.out.println(num2);
     
    //int num = 100;
    System.out.println(num);
    }
    }
     
     
    class VariableDemo {
    public static void main(String[] args) {
    Varialbe v = new Varialbe();
     
    System.out.println(v.num); //访问成员变量
     
    v.show();
     
    }
    }
    ===================================================================
    /*
    形式参数的问题:
    基本类型:形式参数的改变不影响实际参数
    引用类型:形式参数的改变直接影响实际参数
    */
    //形式参数是基本类型
    class Demo {
    public int sum(int a,int b) {
    return a + b;
    }
    }
     
    //形式参数是引用类型
    class Student {
    public void show() {
    System.out.println("我爱学习");
    }
    }
     
    class StudentDemo {
    //如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
    public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
    s.show();
    }
    }
     
    class ArgsTest {
    public static void main(String[] args) {
    //形式参数是基本类型的调用
    Demo d = new Demo();
    int result = d.sum(10,20);
    System.out.println("result:"+result);
    System.out.println("--------------");
     
    //形式参数是引用类型的调用
    //需求:我要调用StudentDemo类中的method()方法
    StudentDemo sd = new StudentDemo();
    //创建学生对象
    Student s = new Student();
    sd.method(s); //把s的地址给到了这里
    }
    }
    ==================================================
    /*
    匿名对象:就是没有名字的对象。
     
    匿名对象的应用场景:
    A:调用方法,仅仅只调用一次的时候。
    注意:调用多次的时候,不适合。
    那么,这种匿名调用有什么好处吗?
    有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
    B:匿名对象可以作为实际参数传递
    */
    class Student {
    public void show() {
    System.out.println("我爱学习");
    }
    }
     
    class StudentDemo {
    public void method(Student s) {
    s.show();
    }
    }
     
    class NoNameDemo {
    public static void main(String[] args) {
    //带名字的调用
    Student s = new Student();
    s.show();
    s.show();
    System.out.println("--------------");
     
    //匿名对象
    //new Student();
    //匿名对象调用方法
    new Student().show();
    new Student().show(); //这里其实是重新创建了一个新的对象
    System.out.println("--------------");
     
     
    //匿名对象作为实际参数传递
    StudentDemo sd = new StudentDemo();
    //Student ss = new Student();
    //sd.method(ss); //这里的s是一个实际参数
    //匿名对象
    sd.method(new Student());
     
    //在来一个
    new StudentDemo().method(new Student());
    }
    }
    ====================================================================/*
    private:
    是一个权限修饰符
    可以修饰成员变量和成员方法
    被其修饰的成员只能在本类中被访问
    */
    class Demo {
    //int num = 10;
    //用private修饰
    private int num = 10;
     
    public void show() {
    System.out.println(num);
    }
     
    private void method() {
    System.out.println("method");
    }
     
    public void function() {
    method();
    }
    }
     
    class PrivateDemo {
    public static void main(String[] args) {
    Demo d = new Demo();
    //不能方法私有的成员变量
    //System.out.println(d.num);
    d.show();
    //不能访问私有的成员方法
    //d.method();
    d.function();
    }
    }
     
    ============================================================
    /*
    定义一个学生类:
    成员变量:name,age
    成员方法:show()方法
     
    我们在使用这个案例的过程中,发现了一个问题:
    通过对象去给成员变量赋值,可以赋值一些非法的数据。
    这是不合理的。
    应该是这个样子的:在赋值之前,先对数据进行判断。
    判断到底在哪里做比较合适呢?
    StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。
    所以,这个判断应该定义在Student类中。
    而我们在成员变量的位置可不可以进行数据判断呢?
    是不可以的,因为做数据校验,必须要依靠一些逻辑语句。
    逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中提供一个方法
    来对数据进行校验。
     
    按照我们前面的分析,我们给出了一个方法进行校验。
    但是呢,它偏偏不调用方法来赋值,还是直接赋值了,
    这样我们的方法就没有起到作用。
    我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。
    怎么去强制要求不能直接使用成员变量呢?
    针对这种情况,Java就提供了一个关键字 private
     
    private:私有的。可以修饰成员变量和成员方法。
    注意:被private修饰的成员只能在本类中访问。
     
    其实我讲到现在讲解的是一个封装的思想。
    封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
    */
    class Student {
    //姓名
    String name;
    //年龄
    private int age;
     
    //写一个方法对数据进行校验
    /*
    返回值类型:void
    参数列表:int a
    */
    public void setAge(int a) {
    if(a < 0 || age > 120) {
    System.out.println("你给的年龄有问题");
    }else {
    age = a;
    }
    }
     
     
    //show()方法,显示所有成员变量值
    public void show() {
    System.out.println("姓名:"+name);
    System.out.println("年龄:"+age);
    }
    }
     
    class StudentDemo {
    public static void main(String[] args) {
    //创建学生对象
    Student s = new Student();
    s.show();
    System.out.println("--------------");
     
    //给成员变量赋值
    s.name = "林青霞";
    //s.age = 27;
    s.setAge(27);
    s.show();
    System.out.println("--------------");
     
    //给age赋值
    //s.age = -27; //这个数据是不合理的
    //通过方法给值
    s.setAge(-27);
    s.show();
    System.out.println("--------------");
    }
    }
    ====================================================================/*
    封装和private的应用:
    A:把成员变量用private修饰
    B:提高对应的getXxx()和setXxx()方法
    */
    //定义学生类
    class Student {
    //姓名
    private String name;
    //年龄
    private int age;
     
    //姓名获取值
    public String getName() {
    return name;
    }
     
    //姓名设置值
    public void setName(String n) {
    name = n;
    }
     
    //年龄获取值
    public int getAge() {
    return age;
    }
     
    //年龄赋值
    public void setAge(int a) {
    age = a;
    }
    }
     
    //测试类
    class StudentTest {
    public static void main(String[] args) {
    //创建学生对象
    Student s = new Student();
     
    //使用成员变量
    //错误:被私有修饰了,外界不能直接访问了
    //System.out.println(s.name+"---"+s.age);
    System.out.println(s.getName()+"---"+s.getAge());
     
    //给成员变量赋值
    //s.name = "林青霞";
    //s.age = 27;
    //通过方法给赋值
    s.setName("林青霞");
    s.setAge(27);
    System.out.println(s.getName()+"---"+s.getAge());
    }
    }
    ======================================================
    /*
    作业:请把手机类写成一个标准类,然后创建对象测试功能。
     
    手机类:
    成员变量:
    品牌:String brand;
    价格:int price;
    颜色:String color;
    成员方法:
    针对每一个成员变量给出对应的getXxx()/setXxx()方法。
    最后定义测试:
    创建一个对象,先通过getXxx()方法输出成员变量的值。这一次的结果是:null---0---null
    然后通过setXxx()方法给成员变量赋值。再次输出结果。这一次的结果是:三星---2999---土豪金
    */
    class Phone {
    //品牌
    private String brand;
    //价格
    private int price;
    //颜色
    private String color;
     
    //getXxx()和setXxx()方法
    public String getBrand() {
    return brand;
    }
     
    public void setBrand(String brand) {
    this.brand = brand;
    }
     
    public int getPrice() {
    return price;
    }
     
    public void setPrice(int price) {
    this.price = price;
    }
     
    public String getColor() {
    return color;
    }
     
    public void setColor(String color) {
    this.color = color;
    }
    }
     
    class PhoneTest {
    public static void main(String[] args) {
    //创建手机对象
    Phone p = new Phone();
     
    //直接输出默认值
    System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor());
     
    //给成员变量赋值
    p.setBrand("三星");
    p.setPrice(2999);
    p.setColor("土豪金");
    //再次输出
    System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor());
    }
    }
    ===========================================================
    /*
    我们曾经曰:起名字要做到见名知意。
     
    this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。
     
    注意:谁调用这个方法,在该方法内部的this就代表谁。
     
    this的场景:
    解决局部变量隐藏成员变量
    */
    //定义学生类
    class Student {
    //姓名
    private String name;
    //年龄
    private int age;
     
    //姓名获取值
    public String getName() {
    return name;
    }
     
    //姓名设置值
    public void setName(String name) { //name = "林青霞";
    //name = name; //变量的使用规则:就近原则
    //这里是类名,目前还没有说过类似的用法,所以这个是有问题的
    //这里的调用只能通过对象名
    //这个对象如果存在,它应该代表的是Student的一个对象。
    //那么,谁能够代表当前类的对象呢? java就提供了一个关键字 this
    //Student.name = name;
    this.name = name;
    }
     
    //年龄获取值
    public int getAge() {
    return age;
    }
     
    //年龄赋值
    public void setAge(int age) {
    this.age = age;
    }
    }
     
    //测试类
    class StudentTest {
    public static void main(String[] args) {
    //创建学生对象
    Student s = new Student();
     
    //给成员变量赋值
    s.setName("林青霞");
    s.setAge(27);
    //获取数据
    System.out.println(s.getName()+"---"+s.getAge());
    }
    }
    ============================
    /*
    标准的代码改进版
     
    this:哪个对象调用那个方法,this就代表那个对象
    */
    class Student {
    private String name;
    private int age;
     
    public String getName() {
    return name; //这里其实是隐含了this
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
    }
     
    class StudentTest2 {
    public static void main(String[] args) {
     
    //创建一个对象
    Student s1 = new Student();
    s1.setName("林青霞");
    s1.setAge(27);
    System.out.println(s1.getName()+"---"+s1.getAge());
     
    //创建第二个对象
    Student s2 = new Student();
    s2.setName("刘意");
    s2.setAge(30);
    System.out.println(s2.getName()+"---"+s2.getAge());
    }
    }
    =============================================================
    /*
    构造方法:
    给对象的数据进行初始化
     
    格式:
    A:方法名与类名相同
    B:没有返回值类型,连void都没有
    C:没有具体的返回值
    */
    class Student {
    private String name; //null
    private int age; //0
     
    public Student() {
    System.out.println("这是构造方法");
    }
    }
     
    class ConstructDemo {
    public static void main(String[] args) {
    //创建对象
    Student s = new Student();
    System.out.println(s); //Student@e5bbd6
    }
    }
    =========================================================
    /*
    我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来的呢?
     
    构造方法的注意事项:
    A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
    B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
    注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
     
    给成员变量赋值有两种方式:
    A:setXxx()
    B:构造方法
    */
     
    class Student {
    private String name;
    private int age;
     
    public Student() {
    //System.out.println("我给了,你还给不");
    System.out.println("这是无参构造方法");
    }
     
    //构造方法的重载格式
    public Student(String name) {
    System.out.println("这是带一个String类型的构造方法");
    this.name = name;
    }
     
    public Student(int age) {
    System.out.println("这是带一个int类型的构造方法");
    this.age = age;
    }
     
    public Student(String name,int age) {
    System.out.println("这是一个带多个参数的构造方法");
    this.name = name;
    this.age = age;
    }
     
    public void show() {
    System.out.println(name+"---"+age);
    }
    }
     
    class ConstructDemo2 {
    public static void main(String[] args) {
    //创建对象
    Student s = new Student();
    s.show();
    System.out.println("-------------");
     
    //创建对象2
    Student s2 = new Student("林青霞");
    s2.show();
    System.out.println("-------------");
     
    //创建对象3
    Student s3 = new Student(27);
    s3.show();
    System.out.println("-------------");
     
    //创建对象4
    Student s4 = new Student("林青霞",27);
    s4.show();
    }
    }
    ==================================================================
    /*
    类的组成:成员变量,成员方法
    今天我们又加入了一个新的成员:构造方法。
    以后再提类的组成:
    成员变量
    构造方法
    成员方法
    根据返回值:
    void类型
    非void类型
    形式参数:
    空参方法
    非空参方法
    */
    class Student {
    public String getString() {
    return "helloworld";
    }
     
    public void show() {
    System.out.println("show");
    }
     
    public void method(String name) {
    System.out.println(name);
    }
     
    public String function(String s1,String s2) {
    return s1+s2;
    }
    }
     
    class StudentDemo {
    public static void main(String[] args) {
    //创建对象
    Student s = new Student();
     
    //调用无参无返回值方法
    s.show();
     
    //调用无参有返回值方法
    String result = s.getString();
    System.out.println(result);
     
    //调用带参无返回值的方法
    s.method("林青霞");
     
    //调用带参带返回值的方法
    String result2 = s.function("hello","world");
    System.out.println(result2);
    }
    }
    =============================================================
    /*
    一个标准代码的最终版。
     
    学生类:
    成员变量:
    name,age
    构造方法:
    无参,带两个参
    成员方法:
    getXxx()/setXxx()
    show():输出该类的所有成员变量值
     
    给成员变量赋值:
    A:setXxx()方法
    B:构造方法
     
    输出成员变量值的方式:
    A:通过getXxx()分别获取然后拼接
    B:通过调用show()方法搞定
    */
    class Student {
    //姓名
    private String name;
    //年龄
    private int age;
     
    //构造方法
    public Student() {
    }
     
    public Student(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    //输出所有的成员变量值
    public void show() {
    System.out.println(name+"---"+age);
    }
    }
     
    //测试类
    class StudentTest {
    public static void main(String[] args) {
    //方式1给成员变量赋值
    //无参构造+setXxx()
    Student s1 = new Student();
    s1.setName("林青霞");
    s1.setAge(27);
    //输出值
    System.out.println(s1.getName()+"---"+s1.getAge());
    s1.show();
    System.out.println("----------------------------");
     
    //方式2给成员变量赋值
    Student s2 = new Student("刘意",30);
    System.out.println(s2.getName()+"---"+s2.getAge());
    s2.show();
    }
    }
    ====================================================================/*
    需求:
    定义一个员工类,自己分析出几个成员,
    然后给出成员变量,构造方法,getXxx()/setXxx()方法,
    以及一个显示所有成员信息的方法。并测试。
     
    分析:
    员工
    成员变量:
    员工编号,姓名,年龄
    构造方法:
    无参构造方法
    成员方法:
    getXxx()/setXxx()
    show();
    */
    class Employee {
    //员工编号
    private String employeeId;
    //姓名
    private String name;
    //年龄
    private int age;
     
    //构造方法
    public Employee() {}
     
    //getXxx()/setXxx()
    public String getEmployeeId() {
    return employeeId;
    }
     
    public void setEmployeeId(String employeeId) {
    this.employeeId = employeeId;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    //显示所有成员信息的方法
    public void show() {
    System.out.println("员工编号是:"+employeeId+"的这个人是:"+name+"的年龄是:"+age);
    }
    }
     
    class EmployeeTest {
    public static void main(String[] args) {
    //创建对象
    Employee e = new Employee();
     
    //给成员变量赋值
    e.setEmployeeId("czbk9527");
    e.setName("唐伯虎");
    e.setAge(18);
     
    //获取数据
    //System.out.println(e.getEmployeeId()+"---"+e.getName()+"---"+e.getAge());
     
    //我们在Employee类中定义了一个show方法。所以,我们改进一下,使用show方法
    e.show();
    }
    }
     
    ===================================================================
    /*
    定义一个类MyMath,提供基本的加减乘除功能,然后进行测试。
    */
    import java.util.Scanner;
     
    class MyMath {
    //加法功能
    public int add(int a,int b) {
    return a + b;
    }
     
    //减法功能
    public int sub(int a,int b) {
    return a - b;
    }
     
    //乘法功能
    public int mul(int a,int b){
    return a * b;
    }
     
    //除法功能
    public int div(int a,int b) {
    return a / b;
    }
    }
     
    //测试类
    class MyMathTest {
    public static void main(String[] args) {
    //创建键盘录入对象
    Scanner sc = new Scanner(System.in);
     
    System.out.println("请输入第一个操作数:");
    int firstNumber = sc.nextInt();
    System.out.println("请输入第二个操作数:");
    int secondNumber = sc.nextInt();
     
    //创建MyMath对象,并使用
    MyMath mm = new MyMath();
     
    System.out.println("加法结果:"+mm.add(firstNumber,secondNumber));
    System.out.println("减法结果:"+mm.sub(firstNumber,secondNumber));
    System.out.println("乘法结果:"+mm.mul(firstNumber,secondNumber));
    System.out.println("除法结果:"+mm.div(firstNumber,secondNumber));
    }
    }
     
     
    ==================================================================
    /*
    定义一个类Demo,其中定义一个求两个数据和的方法,
    定义一个测试了Test,进行测试。
     
    变量什么时候定义为成员变量:
    如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。
     
    变量到底定义在哪里好呢?
    变量的范围是越小越好。因为能及时的被回收。
    */
     
    //方式1
    /*
    class Demo {
    public int sum() {
    int a = 10;
    int b = 20;
    int c = a + b;
    return c;
    }
    }
    */
    //方式1满足了我们的要求,但是不好。
    //因为参与操作的数据现在是固定的。
     
    //方式2
    /*
    class Demo {
    public int sum(int a,int b) {
    return a + b;
    }
    }
    */
     
    //方式2可以满足我们的要求,但是呢我们学习过来面向对象的思想。
    //我就再想,a,b可不可以定义为成员变量呢?
    //如果可以,我们再改进一版
    class Demo {
    int a;
    int b;
     
    public int sum() {
    return a + b;
    }
    }
    //虽然这种方式可以,并且好像是符合了面向对象的思想。
    //但是不好。
    //因为我们曾经说过:类是一组相关的属性和行为的集合。
    //并且类是通过事物转换过来的
    //而类中的成员变量就是事物的属性
    //属性是用来描述事物的
    //同理:成员变量其实是用来描述类的。
     
    //测试类
    class Test {
    public static void main(String[] args) {
    //创建对象
    //方式1测试
    /*
    Demo d = new Demo();
    System.out.println(d.sum());
    */
     
    //方式2测试
    /*
    Demo d = new Demo();
    int a = 10;
    int b = 20;
    System.out.println(d.sum(a,b));
    */
     
    //方式3测试
    Demo d = new Demo();
    d.a = 10;
    d.b = 20;
    System.out.println(d.sum());
    }
    }
    =============================================
    /*
    定义一个长方形类,定义 求周长和面积的方法,
    然后定义一个测试了Test2,进行测试。
     
    长方形的类:
    成员变量:
    长,宽
    成员方法:
    求周长:(长+宽)*2;
    求面积:长*宽
     
    注意:
    import必须出现在所有的class前面。
    */
     
    import java.util.Scanner;
     
    class ChangFangXing {
    //长方形的长
    private int length;
    //长方形的宽
    private int width;
     
    public ChangFangXing(){}
     
    //仅仅提供setXxx()即可
    public void setLength(int length) {
    this.length = length;
    }
     
    public void setWidth(int width) {
    this.width = width;
    }
     
    //求周长
    public int getZhouChang() {
    return (length + width) * 2;
    }
     
    //求面积
    public int getArea() {
    return length * width;
    }
    }
     
    class Test2 {
    public static void main(String[] args) {
    //创建键盘录入对象
    Scanner sc = new Scanner(System.in);
     
    System.out.println("请输入长方形的长:");
    int length = sc.nextInt();
    System.out.println("请输入长方形的宽:");
    int width = sc.nextInt();
     
    //创建对象
    ChangFangXing cfx = new ChangFangXing();
    //先给成员变量赋值
    cfx.setLength(length);
    cfx.setWidth(width);
     
    System.out.println("周长是:"+cfx.getZhouChang());
    System.out.println("面积是:"+cfx.getArea());
    }
    }
    ==============================================================================
    /*
    main方法的格式讲解:
    public static void main(String[] args) {...}
     
    public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
    static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
    void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
    main:是一个常见的方法入口。我见过的语言都是以main作为入口。
    String[] args:这是一个字符串数组。值去哪里了?
    这个东西到底有什么用啊?怎么给值啊?
    这个东西早期是为了接收键盘录入的数据的。
    格式是:
    java MainDemo hello world java
    */
    class MainDemo {
    public static void main(String[] args) {
    //System.out.println(args); //[Ljava.lang.String;@175078b
    //System.out.println(args.length); //0
    //System.out.println(args[0]); //ArrayIndexOutOfBoundsException
     
    //接收数据后
    System.out.println(args);
    System.out.println(args.length);
    //System.out.println(args[0]);
    for(int x=0; x<args.length; x++) {
    System.out.println(args[x]);
    }
    }
    }
     
    ===================================
    /*
    定义一个人类
     
    姓名和年龄都是变化的,这个我能接收,因为每个人的姓名和年龄是不同的。
    但是,我们现在选取的几个人都是中国人,他们的国籍是一样的。
    一样的国籍,我每次创建对象,在堆内存都要开辟这样的空间,
    我就觉得有点浪费了。怎么办呢?
    针对多个对象有共同的这样的成员变量值的时候,
    Java就提高了一个关键字来修饰:static。
    */
    class Person {
    //姓名
    String name;
    //年龄
    int age;
    //国籍
    //String country;
    static String country;
     
    public Person(){}
     
    public Person(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public Person(String name,int age,String country) {
    this.name = name;
    this.age = age;
    this.country = country;
    }
     
    public void show() {
    System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);
    }
    }
     
    class PersonDemo {
    public static void main(String[] args) {
    //创建对象1
    Person p1 = new Person("邓丽君",16,"中国");
    p1.show();
     
    //创建对象2
    //Person p2 = new Person("杨幂",22,"中国");
    //p2.show();
    Person p2 = new Person("杨幂",22);
    p2.show();
     
    //创建对象3
    //Person p3 = new Person("凤姐",20,"中国");
    //p3.show();
    Person p3 = new Person("凤姐",20);
    p3.show();
     
    p3.country = "美国";
    p3.show();
     
    p1.show();
    p2.show();
     
    /*
    姓名:邓丽君,年龄:16,国籍:中国
    姓名:杨幂,年龄:22,国籍:中国
    姓名:凤姐,年龄:20,国籍:中国
    姓名:凤姐,年龄:20,国籍:美国
    姓名:邓丽君,年龄:16,国籍:美国
    姓名:杨幂,年龄:22,国籍:美国
    /*
    }
    }
    ====================================================================/*
    static的特点:(它可以修饰成员变量,还可以修饰成员方法)
    A:随着类的加载而加载
    回想main方法。
    B:优先于对象存在
    C:被类的所有对象共享
    举例:咱们班级的学生应该共用同一个班级编号。
    其实这个特点也是在告诉我们什么时候使用静态?
    如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
    举例:
    饮水机(用静态修饰)
    水杯(不能用静态修饰)
    D:可以通过类名调用
    其实它本身也可以通过对象名调用。
    推荐使用类名调用。
     
    静态修饰的内容一般我们称其为:与类相关的,类成员
    */
    class Student {
    //非静态变量
    int num = 10;
     
    //静态变量
    static int num2 = 20;
    }
     
    class StudentDemo {
    public static void main(String[] args) {
    Student s = new Student();
    System.out.println(s.num);
     
    System.out.println(Student.num2);
    System.out.println(s.num2);
    }
    }
    ===========================================================
    /*
    static关键字注意事项
    A:在静态方法中是没有this关键字的
    如何理解呢?
    静态是随着类的加载而加载,this是随着对象的创建而存在。
    静态比对象先存在。
    B:静态方法只能访问静态的成员变量和静态的成员方法
    静态方法:
    成员变量:只能访问静态变量
    成员方法:只能访问静态成员方法
    非静态方法:
    成员变量:可以是静态的,也可以是非静态的
    成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
    简单记:
    静态只能访问静态。
    */
    class Teacher {
    public int num = 10;
    public static int num2 = 20;
     
    public void show() {
    System.out.println(num); //隐含的告诉你访问的是成员变量
    System.out.println(this.num); //明确的告诉你访问的是成员变量
    System.out.println(num2);
     
    //function();
    //function2();
    }
     
    public static void method() {
    //无法从静态上下文中引用非静态 变量 num
    //System.out.println(num);
    System.out.println(num2);
     
    //无法从静态上下文中引用非静态 方法 function()
    //function();
    function2();
    }
     
    public void function() {
     
    }
     
    public static void function2() {
     
    }
    }
     
    class TeacherDemo {
    public static void main(String[] args) {
    //创建对象
    Teacher t = new Teacher();
    t.show();
    System.out.println("------------");
    t.method();
    }
    }
     
    二.代码块和继承
    /*
    我想要对数组进行操作
     
    在同一个文件夹下,类定义在两个文件中和定义在一个文件中其实一样的。
    */
    class ArrayDemo {
    public static void main(String[] args) {
    //定义数组
    int[] arr = {28,55,37,46,19};
     
    //需求:遍历数组
    /*
    for(int x=0; x<arr.length; x++) {
    if(x == arr.length-1) {
    System.out.println(arr[x]);
    }else {
    System.out.print(arr[x]+", ");
    }
    }
    */
     
    //如果我有多个数组都要进行遍历,那么,代码的重复度就很高
    //如何改进呢?用方法改进
    //调用
    //静态方法
    //printArray(arr);
     
    //非静态方法
    //ArrayDemo ad = new ArrayDemo();
    //ad.printArray(arr);
     
    //测试类的作用:创建其他类的对象,调用其他类的功能。
    //而我们现在的操作是跟数组相关的,所以,你应该把这些操作定义到数组操作类中
    //定义一个数组的操作类
    //有了数组操作类之后的调用
    //ArrayTool at = new ArrayTool();
    //at.printArray(arr);
     
    //方法改进为静态后,就可以直接通过类名调用
    ArrayTool.printArray(arr);
    }
     
    /*
    public static void printArray(int[] arr) {
    for(int x=0; x<arr.length; x++) {
    if(x == arr.length-1) {
    System.out.println(arr[x]);
    }else {
    System.out.print(arr[x]+", ");
    }
    }
    }
    */
     
    //假设该方法不是静态的
    /*
    public void printArray(int[] arr) {
    for(int x=0; x<arr.length; x++) {
    if(x == arr.length-1) {
    System.out.println(arr[x]);
    }else {
    System.out.print(arr[x]+", ");
    }
    }
    }
    */
    }
    ======================================
    class ArrayTool {
     
    //把构造方法私有,外界就不能在创建对象了
    private ArrayTool(){}
     
    public static void printArray(int[] arr) {
    for(int x=0; x<arr.length; x++) {
    if(x == arr.length-1) {
    System.out.println(arr[x]);
    }else {
    System.out.print(arr[x]+", ");
    }
    }
    }
    }
    ==============================
    /*
    我想要对数组进行操作
     
    如何制作一个说明书呢?
    A:写一个工具类
    B:对这个类加入文档注释
    怎么加呢?
    加些什么东西呢?
    C:用工具解析文档注释
    javadoc工具
    D:格式
    javadoc -d 目录 -author -version ArrayTool.java
     
    目录:就可以写一个文件夹的路径
     
    制作帮助文档出错:
    找不到可以文档化的公共或受保护的类:告诉我们类的权限不够
    */
    class ArrayDemo {
    public static void main(String[] args) {
    //定义数组
    int[] arr = {28,55,37,46,19};
     
    //遍历
    ArrayTool.printArray(arr);
     
    //获取最值
    int max = ArrayTool.getMax(arr);
    System.out.println("max:"+max);
     
    //获取55的索引值
    int index = ArrayTool.getIndex(arr,55);
    System.out.println("index:"+index);
    }
    }
    =============================================
    /**
    * 这是针对数组进行操作的工具类
    * @author 刘意
    * @version V.10
    */
    public class ArrayTool {
     
    //把构造方法私有,外界就不能在创建对象了
    /**
    * 这是私有构造
    */
    private ArrayTool(){}
     
    /**
    * 这是遍历数组的方法,遍历后的格式是:[元素1, 元素2, 元素3, ...]
    * @param arr 这是要被遍历的数组
    */
    public static void printArray(int[] arr) {
    System.out.print("[");
    for(int x=0; x<arr.length; x++) {
    if(x == arr.length-1) {
    System.out.println(arr[x]+"]");
    }else {
    System.out.print(arr[x]+", ");
    }
    }
    }
     
    /**
    * 这是获取数组中最大值的方法
    * @param arr 这是要获取最大值的数组
    * @return 返回数组中的最大值
    */
    public static int getMax(int[] arr) {
    int max = arr[0];
     
    for(int x=1; x<arr.length; x++) {
    if(arr[x] > max) {
    max = arr[x];
    }
    }
     
    return max;
    }
     
    /**
    * 获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1
    * @param arr 被查找的数组
    * @param value 要查找的元素
    * @return 返回元素在数组中的索引,如果不存在,返回-1
    */
    public static int getIndex(int[] arr,int value) {
    int index = -1;
     
    for(int x=0; x<arr.length; x++) {
    if(arr[x] == value) {
    index = x;
    break;
    }
    }
     
    return index;
    }
    }
    ====================================
    /*
    猜数字小游戏(数据在1-100之间)
     
    分析:
    A:程序产生一个随机数。(被猜的)
    B:键盘录入数据。(你猜的)
    C:把你猜的和被猜的进行比较
    a:大了
    b:小了
    c:猜中了
    D:给出多次猜的机会,猜中就结束。
    while()循环,猜中就break
    */
    import java.util.Scanner;
     
    class GuessNumber {
    public static void main(String[] args) {
    //程序产生一个随机数。(被猜的)
    int number = (int)(Math.random()*100)+1;
    //System.out.println(number);
     
    //给出多次猜的机会,猜中就结束。
    while(true) {
    //键盘录入数据。(你猜的)
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入你要猜的数据(1-100):");
    int guessNumber = sc.nextInt();
     
    //把你猜的和被猜的进行比较
    if(guessNumber > number) {
    System.out.println("你猜的数据"+guessNumber+"大了");
    }else if(guessNumber < number) {
    System.out.println("你猜的数据"+guessNumber+"小了");
    }else {
    System.out.println("恭喜你,猜中了");
    break;
    }
    }
    }
    }
    =================================================
    /*
    Math:类包含用于执行基本数学运算的方法
     
    由于Math类在java.lang包下,所以不需要导包。
    特点:
    没有构造方法,因为它的成员全部是静态的。
     
    掌握一个方法:
    获取随机数
    public static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
    */
    class MathDemo {
    public static void main(String[] args) {
    //获取一个随机数
    //double d = Math.random();
    //System.out.println(d);
     
    //需求:我要获取一个1-100之间的随机数,肿么办?
    for(int x=0; x<100; x++) {
    int number = (int)(Math.random()*100)+1;
    System.out.println(number);
    }
    }
    }
    ==================================================================
    1:打开帮助文档
    2:点击显示,找到索引,看到输入框
    3:知道你要找谁?以Scanner举例
    4:在输入框里面输入Scanner,然后回车
    5:看包
    java.lang包下的类不需要导入,其他的全部需要导入。
     
    要导入:
    java.util.Scanner
    6:再简单的看看类的解释和说明,别忘了看看该类的版本
    7:看类的结构
    成员变量 字段摘要
    构造方法 构造方法摘要
    成员方法 方法摘要
    8:学习构造方法
    A:有构造方法 就创建对象
    B:没有构造方法 成员可能都是静态的
    9:看成员方法
    A:左边
    是否静态:如果静态,可以通过类名调用
    返回值类型:人家返回什么,你就用什么接收。
    B:右边
    看方法名:方法名称不要写错
    参数列表:人家要什么,你就给什么;人家要几个,你就给几个
    =========================
    /*
    代码块:在Java中,使用{}括起来的代码被称为代码块。
    根据其位置和声明的不同,可以分为
    局部代码块:局部位置,用于限定变量的生命周期。
    构造代码块:在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
    作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化。
    静态代码块:在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
    作用:一般是对类进行初始化。
     
    面试题?
    静态代码块,构造代码块,构造方法的执行顺序?
    静态代码块 -- 构造代码块 -- 构造方法
    静态代码块:只执行一次
    构造代码块:每次调用构造方法都执行
    */
    class Code {
    static {
    int a = 1000;
    System.out.println(a);
    }
     
    //构造代码块
    {
    int x = 100;
    System.out.println(x);
    }
     
    //构造方法
    public Code(){
    System.out.println("code");
    }
     
    //构造方法
    public Code(int a){
    System.out.println("code");
    }
     
    //构造代码块
    {
    int y = 200;
    System.out.println(y);
    }
     
    //静态代码块
    static {
    int b = 2000;
    System.out.println(b);
    }
    }
     
    class CodeDemo {
    public static void main(String[] args) {
    //局部代码块
    {
    int x = 10;
    System.out.println(x);
    }
    //找不到符号
    //System.out.println(x);
    {
    int y = 20;
    System.out.println(y);
    }
    System.out.println("---------------");
     
    Code c = new Code();
    System.out.println("---------------");
    Code c2 = new Code();
    System.out.println("---------------");
    Code c3 = new Code(1);
    }
    }
    =================================
    /*
    写程序的执行结果。
     
    林青霞都60了,我很伤心
    我是main方法
    Student 静态代码块
    Student 构造代码块
    Student 构造方法
    Student 构造代码块
    Student 构造方法
    */
    class Student {
    static {
    System.out.println("Student 静态代码块");
    }
     
    {
    System.out.println("Student 构造代码块");
    }
     
    public Student() {
    System.out.println("Student 构造方法");
    }
    }
     
    class StudentDemo {
    static {
    System.out.println("林青霞都60了,我很伤心");
    }
     
    public static void main(String[] args) {
    System.out.println("我是main方法");
     
    Student s1 = new Student();
    Student s2 = new Student();
    }
    }
    ====================================================================/*
    继承概述:
    把多个类中相同的内容给提取出来定义到一个类中。
     
    如何实现继承呢?
    Java提供了关键字:extends
     
    格式:
    class 子类名 extends 父类名 {}
     
    好处:
    A:提高了代码的复用性
    B:提高了代码的维护性
    C:让类与类之间产生了关系,是多态的前提
     
    类与类产生了关系,其实也是继承的一个弊端:
    类的耦合性增强了。
     
    开发的原则:低耦合,高内聚。
    耦合:类与类的关系
    内聚:就是自己完成某件事情的能力
    */
     
    //使用继承前
    /*
    class Student {
    public void eat() {
    System.out.println("吃饭");
    }
     
    public void sleep() {
    System.out.println("睡觉");
    }
    }
     
    class Teacher {
    public void eat() {
    System.out.println("吃饭");
    }
     
    public void sleep() {
    System.out.println("睡觉");
    }
    }
    */
     
    //使用继承后
    class Person {
    public void eat() {
    System.out.println("吃饭");
    }
     
    public void sleep() {
    System.out.println("睡觉");
    }
    }
     
    class Student extends Person {}
     
    class Teacher extends Person {}
     
    class ExtendsDemo {
    public static void main(String[] args) {
    Student s = new Student();
    s.eat();
    s.sleep();
    System.out.println("-------------");
     
    Teacher t = new Teacher();
    t.eat();
    t.sleep();
    }
    }
    ====================================================
    /*
    Java中继承的特点:
    A:Java只支持单继承,不支持多继承。
    有些语言是支持多继承,格式:extends 类1,类2,...
    B:Java支持多层继承(继承体系)
    */
     
    /*
    class Father {}
    class Mother {}
    class Son exnteds Father {} //正确的
    class Son extends Father,Mother {} // 错误的
    */
     
    class GrandFather {
    public void show() {
    System.out.println("我是爷爷");
    }
    }
     
    class Father extends GrandFather {
    public void method(){
    System.out.println("我是老子");
    }
    }
     
    class Son extends Father {}
     
    class ExtendsDemo2 {
    public static void main(String[] args) {
    Son s = new Son();
    s.method(); //使用父亲的
    s.show(); //使用爷爷的
    }
    }
    ====================================================================/*
    继承的注意事项:
    A:子类只能继承父类所有非私有的成员(成员方法和成员变量)
    B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。
    C:不要为了部分功能而去继承
    class A {
    public void show1(){}
    public void show2(){}
    }
     
    class B {
    public void show2(){}
    public void show3(){}
    }
     
    //我们发现B类中出现了和A类一样的show2()方法,所以,我们就用继承来体现
    class B extends A {
    public void show3(){}
    }
    这样其实不好,因为这样你不但有了show2(),还多了show1()。
    有可能show1()不是你想要的。
     
    那么,我们什么时候考虑使用继承呢?
    继承其实体现的是一种关系:"is a"。
    Person
    Student
    Teacher
    水果
    苹果
    香蕉
    橘子
     
    采用假设法。
    如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。
    */
    class Father {
    private int num = 10;
    public int num2 = 20;
     
    //私有方法,子类不能继承
    private void method() {
    System.out.println(num);
    System.out.println(num2);
    }
     
    public void show() {
    System.out.println(num);
    System.out.println(num2);
    }
    }
     
    class Son extends Father {
    public void function() {
    //num可以在Father中访问private
    //System.out.println(num); //子类不能继承父类的私有成员变量
    System.out.println(num2);
    }
    }
     
    class ExtendsDemo3 {
    public static void main(String[] args) {
    // 创建对象
    Son s = new Son();
    //s.method(); //子类不能继承父类的私有成员方法
    s.show();
    s.function();
    }
    }
    ====================================================================/*
    类的组成:
    成员变量:
    构造方法:
    成员方法:
    而现在我们又讲解了继承,所以,我们就应该来考虑一下,类的组成部分的各自关系。
     
    继承中成员变量的关系:
    A:子类中的成员变量和父类中的成员变量名称不一样,这个太简单。
    B:子类中的成员变量和父类中的成员变量名称一样,这个怎么玩呢?
    在子类方法中访问一个变量的查找顺序:
    a: 在子类方法的局部范围找,有就使用
    b:在子类的成员范围找,有就使用
    c:在父类的成员范围找,有就使用
    d:如果还找不到,就报错。
    */
    class Father {
    public int num = 10;
     
    public void method() {
    int num = 50;
    }
    }
     
    class Son extends Father {
    public int num2 = 20;
    public int num = 30;
     
    public void show() {
    int num = 40;
    System.out.println(num);
    System.out.println(num2);
    // 找不到符号
    System.out.println(num3);
    }
    }
     
    class ExtendsDemo4 {
    public static void main(String[] args) {
    //创建对象
    Son s = new Son();
    s.show();
    }
    }
    ====================================================================/*
    问题是:
    我不仅仅要输出局部范围的num,还要输出本类成员范围的num。怎么办呢?
    我还想要输出父类成员范围的num。怎么办呢?
    如果有一个东西和this相似,但是可以直接访问父类的数据就好了。
    恭喜你,这个关键字是存在的:super。
     
    this和super的区别?
    分别是什么呢?
    this代表本类对应的引用。
    super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
     
    怎么用呢?
    A:调用成员变量
    this.成员变量 调用本类的成员变量
    super.成员变量 调用父类的成员变量
    B:调用构造方法
    this(...) 调用本类的构造方法
    super(...) 调用父类的构造方法
    C:调用成员方法
    this.成员方法 调用本类的成员方法
    super.成员方法 调用父类的成员方法
    */
    class Father {
    public int num = 10;
    }
     
    class Son extends Father {
    public int num = 20;
     
    public void show() {
    int num = 30;
    System.out.println(num);
    System.out.println(this.num);
    System.out.println(super.num);
    }
    }
     
    class ExtendsDemo5 {
    public static void main(String[] args) {
    Son s = new Son();
    s.show();
    }
    }
    ====================================================================/*
    继承中构造方法的关系
    A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
    B:为什么呢?
    因为子类会继承父类中的数据,可能还会使用父类的数据。
    所以,子类初始化之前,一定要先完成父类数据的初始化。
     
    注意:子类每一个构造方法的第一条语句默认都是:super();
    */
    class Father {
    int age;
     
    public Father() {
    System.out.println("Father的无参构造方法");
    }
     
    public Father(String name) {
    System.out.println("Father的带参构造方法");
    }
    }
     
    class Son extends Father {
    public Son() {
    //super();
    System.out.println("Son的无参构造方法");
    }
     
    public Son(String name) {
    //super();
    System.out.println("Son的带参构造方法");
    }
    }
     
    class ExtendsDemo6 {
    public static void main(String[] args) {
    //创建对象
    Son s = new Son();
    System.out.println("------------");
    Son s2 = new Son("林青霞");
    }
    }
    ====================================================================/*
    如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
    报错。
    如何解决呢?
    A:在父类中加一个无参构造方法
    B:通过使用super关键字去显示的调用父类的带参构造方法
    C:子类通过this去调用本类的其他构造方法
    子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。
     
    注意事项:
    this(...)或者super(...)必须出现在第一条语句上。
    如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
    */
    class Father {
    /*
    public Father() {
    System.out.println("Father的无参构造方法");
    }
    */
     
    public Father(String name) {
    System.out.println("Father的带参构造方法");
    }
    }
     
    class Son extends Father {
    public Son() {
    super("随便给");
    System.out.println("Son的无参构造方法");
    //super("随便给");
    }
     
    public Son(String name) {
    //super("随便给");
    this();
    System.out.println("Son的带参构造方法");
    }
    }
     
    class ExtendsDemo7 {
    public static void main(String[] args) {
    Son s = new Son();
    System.out.println("----------------");
    Son ss = new Son("林青霞");
    }
    }
    ==================================================
    /*
    继承中成员方法的关系:
    A:子类中的方法和父类中的方法声明不一样,这个太简单。
    B:子类中的方法和父类中的方法声明一样,这个该怎么玩呢?
    通过子类对象调用方法:
    a:先找子类中,看有没有这个方法,有就使用
    b:再看父类中,有没有这个方法,有就使用
    c:如果没有就报错。
    */
    class Father {
    public void show() {
    System.out.println("show Father");
    }
    }
     
    class Son extends Father {
    public void method() {
    System.out.println("method Son");
    }
     
    public void show() {
    System.out.println("show Son");
    }
    }
     
    class ExtendsDemo8 {
    public static void main(String[] args) {
    //创建对象
    Son s = new Son();
    s.show();
    s.method();
    //s.fucntion(); //找不到符号
    }
    }
    ============================================================
    /*
    方法重写:子类中出现了和父类中方法声明一模一样的方法。
     
    方法重载:
    本类中出现的方法名一样,参数列表不同的方法。与返回值无关。
     
    子类对象调用方法的时候:
    先找子类本身,再找父类。
     
    方法重写的应用:
    当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
    这样,即沿袭了父类的功能,又定义了子类特有的内容。
     
    案例:
    A:定义一个手机类。
    B:通过研究,我发明了一个新手机,这个手机的作用是在打完电话后,可以听天气预报。
    按照我们基本的设计,我们把代码给写出来了。
    但是呢?我们又发现新手机应该是手机,所以,它应该继承自手机。
    其实这个时候的设计,并不是最好的。
    因为手机打电话功能,是手机本身就具备的最基本的功能。
    所以,我的新手机是不用在提供这个功能的。
    但是,这个时候,打电话功能就没有了。这个不好。
    最终,还是加上这个功能。由于它继承了手机类,所以,我们就直接使用父类的功能即可。
    那么,如何使用父类的功能呢?通过super关键字调用
    */
    class Phone {
    public void call(String name) {
    System.out.println("给"+name+"打电话");
    }
    }
     
    class NewPhone extends Phone {
    public void call(String name) {
    //System.out.println("给"+name+"打电话");
    super.call(name);
    System.out.println("可以听天气预报了");
    }
    }
     
    class ExtendsDemo9 {
    public static void main(String[] args) {
    NewPhone np = new NewPhone();
    np.call("林青霞");
    }
    }
    ============================================================
    /*
    方法重写的注意事项
    A:父类中私有方法不能被重写
    因为父类私有方法子类根本就无法继承
    B:子类重写父类方法时,访问权限不能更低
    最好就一致
    C:父类静态方法,子类也必须通过静态方法进行重写
    其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解
     
    子类重写父类方法的时候,最好声明一模一样。
    */
    class Father {
    //private void show() {}
     
    /*
    public void show() {
    System.out.println("show Father");
    }
    */
     
    void show() {
    System.out.println("show Father");
    }
    /*
    public static void method() {
     
    }
    */
     
    public void method() {
     
    }
    }
     
    class Son extends Father {
    //private void show() {}
     
    /*
    public void show() {
    System.out.println("show Son");
    }
    */
     
    public void show() {
    System.out.println("show Son");
    }
     
     
    public static void method() {
     
    }
     
    /*
    public void method() {
     
    }
    */
    }
     
    class ExtendsDemo10 {
    public static void main(String[] args) {
    Son s = new Son();
    s.show();
    }
    }
     
    ================================================================
    /*
    看程序写结果:
    A:成员变量 就近原则
    B:this和super的问题
    this访问本类的成员
    super访问父类的成员
    C:子类构造方法执行前默认先执行父类的无参构造方法
    D:一个类的初始化过程
    成员变量进行初始化
    默认初始化
    显示初始化
    构造方法初始化
     
    结果:
    fu
    zi
    30
    20
    10
    */
    class Fu{
    public int num = 10;
    public Fu(){
    System.out.println("fu");
    }
    }
    class Zi extends Fu{
    public int num = 20;
    public Zi(){
    System.out.println("zi");
    }
    public void show(){
    int num = 30;
    System.out.println(num); //30
    System.out.println(this.num); //20
    System.out.println(super.num); //10
    }
    }
    class ExtendsTest {
    public static void main(String[] args) {
    Zi z = new Zi();
    z.show();
    }
    }
    =====================================================
    /*
    看程序写结果:
    A:一个类的静态代码块,构造代码块,构造方法的执行流程
    静态代码块 > 构造代码块 > 构造方法
    B:静态的内容是随着类的加载而加载
    静态代码块的内容会优先执行
    C:子类初始化之前先会进行父类的初始化
     
    结果是:
    静态代码块Fu
    静态代码块Zi
    构造代码块Fu
    构造方法Fu
    构造代码块Zi
    构造方法Zi
    */
    class Fu {
    static {
    System.out.println("静态代码块Fu");
    }
     
    {
    System.out.println("构造代码块Fu");
    }
     
    public Fu() {
    System.out.println("构造方法Fu");
    }
    }
     
    class Zi extends Fu {
    static {
    System.out.println("静态代码块Zi");
    }
     
    {
    System.out.println("构造代码块Zi");
    }
     
    public Zi() {
    System.out.println("构造方法Zi");
    }
    }
     
    class ExtendsTest2 {
    public static void main(String[] args) {
    Zi z = new Zi();
    }
    }
     
     
    ==========================================================
    /*
    学生案例和老师案例讲解
     
    学生:
    成员变量;姓名,年龄
    构造方法:无参,带参
    成员方法:getXxx()/setXxx()
    老师:
    成员变量;姓名,年龄
    构造方法:无参,带参
    成员方法:getXxx()/setXxx()
    */
    //定义学生类
    class Student {
    //姓名
    private String name;
    //年龄
    private int age;
     
    public Student() {
    }
     
    public Student(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
    }
     
    //定义老师类
    class Teacher {
    //姓名
    private String name;
    //年龄
    private int age;
     
    public Teacher() {
    }
     
    public Teacher(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
    }
     
    class ExtendsTest3 {
    public static void main(String[] args) {
    //创建学生对象并测试
    //方式1
    Student s1 = new Student();
    s1.setName("林青霞");
    s1.setAge(27);
    System.out.println(s1.getName()+"---"+s1.getAge());
     
    //方式2
    Student s2 = new Student("林青霞",27);
    System.out.println(s2.getName()+"---"+s2.getAge());
     
    //对应的老师测试我不想了,留给你们自己练习。
    }
    }
    ===================================================================
    /*
    学生案例和老师案例讲解
     
    学生:
    成员变量;姓名,年龄
    构造方法:无参,带参
    成员方法:getXxx()/setXxx()
    老师:
    成员变量;姓名,年龄
    构造方法:无参,带参
    成员方法:getXxx()/setXxx()
     
    看上面两个类的成员,发现了很多相同的东西,所以我们就考虑抽取一个共性的类:
    人:
    成员变量;姓名,年龄
    构造方法:无参,带参
    成员方法:getXxx()/setXxx()
     
    学生 继承 人
    老师 继承 人
    */
    //定义人类
    class Person {
    //姓名
    private String name;
    //年龄
    private int age;
     
    public Person() {
    }
     
    public Person(String name,int age) { //"林青霞",27
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
    }
     
    //定义学生类
    class Student extends Person {
    public Student() {}
     
    public Student(String name,int age) { //"林青霞",27
    //this.name = name;
    //this.age = age;
    super(name,age);
    }
    }
     
    //定义老师类
    class Teacher extends Person {
     
    }
     
    class ExtendsTest4 {
    public static void main(String[] args) {
    //创建学生对象并测试
    //方式1
    Student s1 = new Student();
    s1.setName("林青霞");
    s1.setAge(27);
    System.out.println(s1.getName()+"---"+s1.getAge());
     
    //方式2
    Student s2 = new Student("林青霞",27);
    System.out.println(s2.getName()+"---"+s2.getAge());
     
    //补齐老师类中的代码并进行测试。
    }
    }
    ====================================================================
    /*
    猫狗案例讲解
     
    先找到具体的事物,然后发现具体的事物有共性,才提取出一个父类。
     
    猫:
    成员变量:姓名,年龄,颜色
    构造方法:无参,带参
    成员方法:
    getXxx()/setXxx()
    eat()
    palyGame()
    狗:
    成员变量:姓名,年龄,颜色
    构造方法:无参,带参
    成员方法:
    getXxx()/setXxx()
    eat()
    lookDoor()
     
    共性:
    成员变量:姓名,年龄,颜色
    构造方法:无参,带参
    成员方法:
    getXxx()/setXxx()
    eat()
     
    把共性定义到一个类中,这个类的名字叫:动物。
    动物类:
    成员变量:姓名,年龄,颜色
    构造方法:无参,带参
    成员方法:
    getXxx()/setXxx()
    eat()
     
    猫:
    构造方法:无参,带参
    成员方法:palyGame()
    狗:
    构造方法:无参,带参
    成员方法:lookDoor()
    */
    //定义动物类
    class Animal {
    //姓名
    private String name;
    //年龄
    private int age;
    //颜色
    private String color;
     
    public Animal() {}
     
    public Animal(String name,int age,String color) {
    this.name = name;
    this.age = age;
    this.color = color;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    public String getColor() {
    return color;
    }
     
    public void setColor(String color) {
    this.color = color;
    }
     
    public void eat() {
    System.out.println("不要睡了,该吃饭了");
    }
    }
     
    //定义猫类
    class Cat extends Animal {
    public Cat() {}
     
    public Cat(String name,int age,String color) {
    super(name,age,color);
    }
     
    public void playGame() {
    System.out.println("猫玩英雄联盟");
    }
    }
     
    //定义狗类
    class Dog extends Animal {
    public Dog() {}
     
    public Dog(String name,int age,String color) {
    super(name,age,color);
    }
     
    public void lookDoor() {
    System.out.println("狗看家");
    }
    }
     
    //测试类
    class ExtendsTest5 {
    public static void main(String[] args) {
    //测试猫
    //方式1
    Cat c1 = new Cat();
    c1.setName("Tom");
    c1.setAge(3);
    c1.setColor("白色");
    System.out.println("猫的名字是:"+c1.getName()+";年龄是:"+c1.getAge()+";颜色是:"+c1.getColor());
    c1.eat();
    c1.playGame();
    System.out.println("---------------");
     
    //方式2
    Cat c2 = new Cat("杰瑞",5,"土豪金");
    System.out.println("猫的名字是:"+c2.getName()+";年龄是:"+c2.getAge()+";颜色是:"+c2.getColor());
    c2.eat();
    c2.playGame();
     
    //作业:测试狗
    }
    }
     
    ==============================================================================================================================
    /*
    看程序写结果:
    A:成员变量的问题
    int x = 10; //成员变量是基本类型
    Student s = new Student(); //成员变量是引用类型
    B:一个类的初始化过程
    成员变量的初始化
    默认初始化
    显示初始化
    构造方法初始化
    C:子父类的初始化(分层初始化)
    先进行父类初始化,然后进行子类初始化。
     
    结果:
    YXYZ
     
    问题:
    虽然子类中构造方法默认有一个super()
    初始化的时候,不是按照那个顺序进行的。
    而是按照分层初始化进行的。
    它仅仅表示要先初始化父类数据,再初始化子类数据。
    */
    class X {
    Y b = new Y();
    X() {
    System.out.print("X");
    }
    }
     
    class Y {
    Y() {
    System.out.print("Y");
    }
    }
     
    public class Z extends X {
    Y y = new Y();
    Z() {
    //super
    System.out.print("Z");
    }
    public static void main(String[] args) {
    new Z();
    }
    }
    ========================
    首先我来写两个代码:
    //定义学生类
    class Student {
    String name;
    int age;
     
    public Student(){}
     
    //getXxx()/setXxx()
     
    public void eat() {
    System.out.println("吃饭");
    }
    }
     
    //定义老师类
    class Teacher {
    String name;
    int age;
     
    public Teacher(){}
     
    //getXxx()/setXxx()
     
    public void eat() {
    System.out.println("吃饭");
    }
    }
    我们观察上面两个代码:
    发现name,age成员变量,以及getXxx()/setXxx(),还有eat()等都是相同的。
    如果我们后来继续定义类,举例:工人类,军人类。他们是不是也具备这些内容。
    那么,我们每一次定义这样的类的时候,都要把这些重复的内容都重新定义一遍。
    麻烦不?麻烦。所以,我们要考虑改进?
    如何改进呢?
    我这想的:我能不能把这些相同的内容给定义到一个独立的类中。
    然后,让这多个类和这个独立的类产生一个关系,有了这个关系后,
    这多个类就可以具备这个独立的类的功能。
    为了实现这个效果,java就提供了一个技术:继承。
     
    父亲:
    4个儿子
    继承怎么表示呢?继承的格式是什么样子的呢?
    class Fu {}
     
    class Zi extends Fu {
     
    }
     
    我们就回头修改我们的代码:
    class Person {
    String name;
    int age;
     
    public Person(){}
     
    //getXxx()/setXxx()
     
    public void eat() {
    System.out.println("吃饭");
    }
    }
     
    class Student extends Person {
    public Student(){}
    }
     
    class Teacher extends Person {
    public Teacher(){}
    }
    ===============================================================================================
    1:方法重写和方法重载的区别?方法重载能改变返回值类型吗?
     
    方法重写:
    在子类中,出现和父类中一模一样的方法声明的现象。
     
    方法重载:
    同一个类中,出现的方法名相同,参数列表不同的现象。
     
     
    方法重载能改变返回值类型,因为它和返回值类型无关。
     
     
    Override:方法重写
    Overload:方法重载
     
    2:this关键字和super关键字分别代表什么?以及他们各自的使用场景和作用。
     
    this:代表当前类的对象引用
    super:代表父类存储空间的标识。(可以理解为父类的引用,通过这个东西可以访问父类的成员)
     
    场景:
    成员变量:
    this.成员变量
    super.成员变量
    构造方法:
    this(...)
    super(...)
    成员方法:
    this.成员方法
    super.成员方法
     
    三.多态,抽象,接口
    /*
    final可以修饰类,方法,变量
     
    特点:
    final可以修饰类,该类不能被继承。
    final可以修饰方法,该方法不能被重写。(覆盖,复写)
    final可以修饰变量,该变量不能被重新赋值。因为这个变量其实常量。
     
    常量:
    A:字面值常量
    "hello",10,true
    B:自定义常量
    final int x = 10;
    */
     
    //final class Fu //无法从最终Fu进行继承
     
    class Fu {
    public int num = 10;
    public final int num2 = 20;
     
    /*
    public final void show() {
     
    }
    */
    }
     
    class Zi extends Fu {
    // Zi中的show()无法覆盖Fu中的show()
    public void show() {
    num = 100;
    System.out.println(num);
     
    //无法为最终变量num2分配值
    //num2 = 200;
    System.out.println(num2);
    }
    }
     
    class FinalDemo {
    public static void main(String[] args) {
    Zi z = new Zi();
    z.show();
    }
    }
    ===============================================================
    /*
    面试题:final修饰局部变量的问题
    基本类型:基本类型的值不能发生改变。
    引用类型:引用类型的地址值不能发生改变,但是,该对象的堆内存的值是可以改变的。
    */
    class Student {
    int age = 10;
    }
     
    class FinalTest {
    public static void main(String[] args) {
    //局部变量是基本数据类型
    int x = 10;
    x = 100;
    System.out.println(x);
    int y = 10;
    //无法为最终变量y分配值
    //y = 100;
    System.out.println(y);
    System.out.println("--------------");
     
    //局部变量是引用数据类型
    Student s = new Student();
    System.out.println(s.age);
    s.age = 100;
    System.out.println(s.age);
    System.out.println("--------------");
     
    final Student ss = new Student();
    System.out.println(ss.age);
    ss.age = 100;
    System.out.println(ss.age);
     
    //重新分配内存空间
    //无法为最终变量ss分配值
    //ss = new Student();
     
    //100
    100
    =================
    10
    100
    10
    100
    }
    }
    ========================================================================================
    /*
    final修饰变量的初始化时机
    A:被final修饰的变量只能赋值一次。
    B:在构造方法完毕前。(非静态的常量)
    */
    class Demo {
    //int num = 10;
    //final int num2 = 20;
     
    int num;
    final int num2;
     
    {
    //num2 = 10;
    }
     
    public Demo() {
    num = 100;
    //无法为最终变量num2分配值
    num2 = 200;
    }
    }
     
    class FinalTest2 {
    public static void main(String[] args) {
    Demo d = new Demo();
    System.out.println(d.num);
    System.out.println(d.num2);
    }
    }
    ==============================================
    /*
    继承的代码体现
     
    由于继承中方法有一个现象:方法重写。
    所以,父类的功能,就会被子类给覆盖调。
    有些时候,我们不想让子类去覆盖掉父类的功能,只能让他使用。
    这个时候,针对这种情况,Java就提供了一个关键字:final
     
    final:最终的意思。常见的是它可以修饰类,方法,变量。
    */
    class Fu {
    public final void show() {
    System.out.println("这里是绝密资源,任何人都不能修改");
    }
    }
     
    class Zi extends Fu {
    // Zi中的show()无法覆盖Fu中的show()
    public void show() {
    System.out.println("这是一堆垃圾");
    }
    }
     
    class ZiDemo {
    public static void main(String[] args) {
    Zi z = new Zi();
    z.show();
    }
    }
    ======================================================
    /*
    多态:同一个对象(事物),在不同时刻体现出来的不同状态。
    举例:
    猫是猫,猫是动物。
    水(液体,固体,气态)。
     
    多态的前提:
    A:要有继承关 系。
    B:要有方法重写。
    其实没有也是可以的,但是如果没有这个就没有意义。
    动物 d = new 猫();
    d.show();
    动物 d = new 狗();
    d.show();
    C:要有父类引用指向子类对象。
    父 f = new 子();
     
    用代码体现一下多态。
     
    多态中的成员访问特点:
    A:成员变量
    编译看左边,运行看左边。
    B:构造方法
    创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。
    C:成员方法
    编译看左边,运行看右边。
    D:静态方法
    编译看左边,运行看左边。
    (静态和类相关,算不上重写,所以,访问还是左边的)
     
    由于成员方法存在方法重写,所以它运行看右边。
    */
    class Fu {
    public int num = 100;
     
    public void show() {
    System.out.println("show Fu");
    }
     
    public static void function() {
    System.out.println("function Fu");
    }
    }
     
    class Zi extends Fu {
    public int num = 1000;
    public int num2 = 200;
     
    public void show() {
    System.out.println("show Zi");
    }
     
    public void method() {
    System.out.println("method zi");
    }
     
    public static void function() {
    System.out.println("function Zi");
    }
    }
     
    class DuoTaiDemo {
    public static void main(String[] args) {
    //要有父类引用指向子类对象。
    //父 f = new 子();
    Fu f = new Zi();
    System.out.println(f.num);//100
    //找不到符号
    //System.out.println(f.num2);
     
    f.show();//show zi
    //找不到符号
    //f.method();
    f.function();//function fu
     
    }
    }
    ==========================================================
    /*
    多态的好处:
    A:提高了代码的维护性(继承保证)
    B:提高了代码的扩展性(由多态保证)
     
    猫狗案例代码
    */
    class Animal {
    public void eat(){
    System.out.println("eat");
    }
     
    public void sleep(){
    System.out.println("sleep");
    }
    }
     
    class Dog extends Animal {
    public void eat(){
    System.out.println("狗吃肉");
    }
     
    public void sleep(){
    System.out.println("狗站着睡觉");
    }
    }
     
    class Cat extends Animal {
    public void eat() {
    System.out.println("猫吃鱼");
    }
     
    public void sleep() {
    System.out.println("猫趴着睡觉");
    }
    }
     
    class Pig extends Animal {
    public void eat() {
    System.out.println("猪吃白菜");
    }
     
    public void sleep() {
    System.out.println("猪侧着睡");
    }
    }
     
    //针对动物操作的工具类
    class AnimalTool {
    private AnimalTool(){}
     
    /*
    //调用猫的功能
    public static void useCat(Cat c) {
    c.eat();
    c.sleep();
    }
     
    //调用狗的功能
    public static void useDog(Dog d) {
    d.eat();
    d.sleep();
    }
     
    //调用猪的功能
    public static void usePig(Pig p) {
    p.eat();
    p.sleep();
    }
    */
    public static void useAnimal(Animal a) {
    a.eat();
    a.sleep();
    }
     
    }
     
    class DuoTaiDemo2 {
    public static void main(String[] args) {
    //我喜欢猫,就养了一只
    Cat c = new Cat();
    c.eat();
    c.sleep();
     
    //我很喜欢猫,所以,又养了一只
    Cat c2 = new Cat();
    c2.eat();
    c2.sleep();
     
    //我特别喜欢猫,又养了一只
    Cat c3 = new Cat();
    c3.eat();
    c3.sleep();
    //...
    System.out.println("--------------");
    //问题来了,我养了很多只猫,每次创建对象是可以接受的
    //但是呢?调用方法,你不觉得很相似吗?仅仅是对象名不一样。
    //我们准备用方法改进
    //调用方式改进版本
    //useCat(c);
    //useCat(c2);
    //useCat(c3);
     
    //AnimalTool.useCat(c);
    //AnimalTool.useCat(c2);
    //AnimalTool.useCat(c3);
     
    AnimalTool.useAnimal(c);
    AnimalTool.useAnimal(c2);
    AnimalTool.useAnimal(c3);
    System.out.println("--------------");
     
    //我喜欢狗
    Dog d = new Dog();
    Dog d2 = new Dog();
    Dog d3 = new Dog();
    //AnimalTool.useDog(d);
    //AnimalTool.useDog(d2);
    //AnimalTool.useDog(d3);
    AnimalTool.useAnimal(d);
    AnimalTool.useAnimal(d2);
    AnimalTool.useAnimal(d3);
    System.out.println("--------------");
     
    //我喜欢宠物猪
    //定义一个猪类,它要继承自动物,提供两个方法,并且还得在工具类中添加该类方法调用
    Pig p = new Pig();
    Pig p2 = new Pig();
    Pig p3 = new Pig();
    //AnimalTool.usePig(p);
    //AnimalTool.usePig(p2);
    //AnimalTool.usePig(p3);
    AnimalTool.useAnimal(p);
    AnimalTool.useAnimal(p2);
    AnimalTool.useAnimal(p3);
    System.out.println("--------------");
     
    //我喜欢宠物狼,老虎,豹子...
    //定义对应的类,继承自动物,提供对应的方法重写,并在工具类添加方法调用
    //前面几个必须写,我是没有意见的
    //但是,工具类每次都改,麻烦不
    //我就想,你能不能不改了
    //太简单:把所有的动物都写上。问题是名字是什么呢?到底哪些需要被加入呢?
    //改用另一种解决方案。
     
    }
     
    /*
    //调用猫的功能
    public static void useCat(Cat c) {
    c.eat();
    c.sleep();
    }
     
    //调用狗的功能
    public static void useDog(Dog d) {
    d.eat();
    d.sleep();
    }
    */
    }
    ====================================================================/*
    多态的弊端:
    不能使用子类的特有功能。
    */
    class Fu {
    public void show() {
    System.out.println("show fu");
    }
    }
     
    class Zi extends Fu {
    public void show() {
    System.out.println("show zi");
    }
     
    public void method() {
    System.out.println("method zi");
    }
     
    }
     
    class DuoTaiDemo3 {
    public static void main(String[] args) {
    //测试
    Fu f = new Zi();
    f.show();
    //f.method();//不能访问
    }
    }
    =========================================================
    /*
    多态的弊端:
    不能使用子类的特有功能。
     
    我就想使用子类的特有功能?行不行?
    行。
     
    怎么用呢?
    A:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,太占内存了)
    B:把父类的引用强制转换为子类的引用。(向下转型)
     
    对象间的转型问题:
    向上转型:
    Fu f = new Zi();
    向下转型:
    Zi z = (Zi)f; //要求该f必须是能够转换为Zi的。
    */
    class Fu {
    public void show() {
    System.out.println("show fu");
    }
    }
     
    class Zi extends Fu {
    public void show() {
    System.out.println("show zi");
    }
     
    public void method() {
    System.out.println("method zi");
    }
     
    }
     
    class DuoTaiDemo4 {
    public static void main(String[] args) {
    //测试
    Fu f = new Zi();
    f.show();
    //f.method();
     
    //创建子类对象
    //Zi z = new Zi();
    //z.show();
    //z.method();
     
    //你能够把子的对象赋值给父亲,那么我能不能把父的引用赋值给子的引用呢?
    //如果可以,但是如下
    Zi z = (Zi)f;
    z.show();
    z.method();
    }
    }
    ===========================================================
    多态的问题理解:
    class 孔子爹 {
    public int age = 40;
     
    public void teach() {
    System.out.println("讲解JavaSE");
    }
    }
     
    class 孔子 extends 孔子爹 {
    public int age = 20;
     
    public void teach() {
    System.out.println("讲解论语");
    }
     
    public void playGame() {
    System.out.println("英雄联盟");
    }
    }
     
    //Java培训特别火,很多人来请孔子爹去讲课,这一天孔子爹被请走了
    //但是还有人来请,就剩孔子在家,价格还挺高。孔子一想,我是不是可以考虑去呢?
    //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹
    //向上转型
    孔子爹 k爹 = new 孔子();
    //到人家那里去了
    System.out.println(k爹.age); //40
    k爹.teach(); //讲解论语
    //k爹.playGame(); //这是儿子才能做的
     
     
    //讲完了,下班回家了
    //脱下爹的装备,换上自己的装备
    //向下转型
    孔子 k = (孔子) k爹;
    System.out.println(k.age); //20
    k.teach(); //讲解论语
    k.playGame(); //英雄联盟
     
    ====================================================================/*
    ClassCastException:类型转换异常
    一般在多态的向下转型中容易出现
    */
    class Animal {
    public void eat(){}
    }
     
    class Dog extends Animal {
    public void eat() {}
     
    public void lookDoor() {
     
    }
    }
     
    class Cat extends Animal {
    public void eat() {
     
    }
     
    public void playGame() {
     
    }
    }
     
    class DuoTaiDemo5 {
    public static void main(String[] args) {
    //内存中的是狗
    Animal a = new Dog();
    Dog d = (Dog)a;
     
    //内存中是猫
    a = new Cat();
    Cat c = (Cat)a;
     
    //内存中是猫
    Dog dd = (Dog)a; //ClassCastException
    }
    }
    =================================================
    /*
    多态练习:猫狗案例
    */
    class Animal {
    public void eat(){
    System.out.println("吃饭");
    }
    }
     
    class Dog extends Animal {
    public void eat() {
    System.out.println("狗吃肉");
    }
     
    public void lookDoor() {
    System.out.println("狗看门");
    }
    }
     
    class Cat extends Animal {
    public void eat() {
    System.out.println("猫吃鱼");
    }
     
    public void playGame() {
    System.out.println("猫捉迷藏");
    }
    }
     
    class DuoTaiTest {
    public static void main(String[] args) {
    //定义为狗
    Animal a = new Dog();
    a.eat();
    System.out.println("--------------");
    //还原成狗
    Dog d = (Dog)a;
    d.eat();
    d.lookDoor();
    System.out.println("--------------");
    //变成猫
    a = new Cat();
    a.eat();
    System.out.println("--------------");
    //还原成猫
    Cat c = (Cat)a;
    c.eat();
    c.playGame();
    System.out.println("--------------");
     
    //演示错误的内容
    //Dog dd = new Animal();
    //Dog ddd = new Cat();
    //ClassCastException
    //Dog dd = (Dog)a;
    }
    }
     
    ===============================================
    /*
    不同地方饮食文化不同的案例
    */
    class Person {
    public void eat() {
    System.out.println("吃饭");
    }
    }
     
    class SouthPerson extends Person {
    public void eat() {
    System.out.println("炒菜,吃米饭");
    }
     
    public void jingShang() {
    System.out.println("经商");
    }
    }
     
    class NorthPerson extends Person {
    public void eat() {
    System.out.println("炖菜,吃馒头");
    }
     
    public void yanJiu() {
    System.out.println("研究");
    }
    }
     
    class DuoTaiTest2 {
    public static void main(String[] args) {
    //测试
    //南方人
    Person p = new SouthPerson();
    p.eat();
    System.out.println("-------------");
    SouthPerson sp = (SouthPerson)p;
    sp.eat();
    sp.jingShang();
    System.out.println("-------------");
     
    //北方人
    p = new NorthPerson();
    p.eat();
    System.out.println("-------------");
    NorthPerson np = (NorthPerson)p;
    np.eat();
    np.yanJiu();
    }
    }
    ===================================================
    /*
    看程序写结果:先判断有没有问题,如果没有,写出结果
    */
    class Fu {
    public void show() {
    System.out.println("fu show");
    }
    }
     
    class Zi extends Fu {
    public void show() {
    System.out.println("zi show");
    }
     
    public void method() {
    System.out.println("zi method");
    }
    }
     
    class DuoTaiTest3 {
    public static void main(String[] args) {
    Fu f = new Zi();
    //找不到符号
    //f.method();
    f.show(); //zi show
    }
    }
    ==========================================================
    /*
    看程序写结果:先判断有没有问题,如果没有,写出结果
     
    多态的成员访问特点:
    方法:编译看左边,运行看右边。
     
    继承的时候:
    子类中有和父类中一样的方法,叫重写。
    子类中没有父亲中出现过的方法,方法就被继承过来了。
    */
    class A {
    public void show() {
    show2();
    }
    public void show2() {
    System.out.println("我");
    }
    }
    class B extends A {
    /*
    public void show() {
    show2();
    }
    */
     
    public void show2() {
    System.out.println("爱");
    }
    }
    class C extends B {
    public void show() {
    super.show();
    }
    public void show2() {
    System.out.println("你");
    }
    }
    public class DuoTaiTest4 {
    public static void main(String[] args) {
    A a = new B();
    a.show();
     
    B b = new C();
    b.show();
    }
    }
    ====================================================================
    /*
    抽象类的概述:
    动物不应该定义为具体的东西,而且动物中的吃,睡等也不应该是具体的。
    我们把一个不是具体的功能称为抽象的功能,而一个类中如果有抽象的功能,该类必须是抽象类。
     
    抽象类的特点:
    A:抽象类和抽象方法必须用abstract关键字修饰
    B:抽象类中不一定有抽象方法,但是有抽象方法的类必须定义为抽象类
    C:抽象类不能实例化 不能创建对象
    因为它不是具体的。
    抽象类有构造方法,但是不能实例化?构造方法的作用是什么呢?
    用于子类访问父类数据的初始化
    D:抽象的子类
    a:如果不想重写抽象方法,该子类是一个抽象类。
    b:重写所有的抽象方法,这个时候子类是一个具体的类。
     
    抽象类的实例化其实是靠具体的子类实现的。是多态的方式。
    Animal a = new Cat();
    */
     
    //abstract class Animal //抽象类的声明格式
    abstract class Animal {
    //抽象方法
    //public abstract void eat(){} //空方法体,这个会报错。抽象方法不能有主体
    public abstract void eat();
     
    public Animal(){}
    }
     
    //子类是抽象类
    abstract class Dog extends Animal {}
     
    //子类是具体类,重写抽象方法
    class Cat extends Animal {
    public void eat() {
    System.out.println("猫吃鱼");
    }
    }
     
    class AbstractDemo {
    public static void main(String[] args) {
    //创建对象
    //Animal是抽象的; 无法实例化
    //Animal a = new Animal();
    //通过多态的方式
    Animal a = new Cat();
    a.eat();
    }
    }
    ====================================================================
    /*
    抽象类的成员特点:
    成员变量:既可以是变量,也可以是常量。
    构造方法:有。
    用于子类访问父类数据的初始化。
    成员方法:既可以是抽象的,也可以是非抽象的。
     
    抽象类的成员方法特性:
    A:抽象方法 强制要求子类做的事情。
    B:非抽象方法 子类继承的事情,提高代码复用性。
    */
    abstract class Animal {
    public int num = 10;
    public final int num2 = 20;
     
    public Animal() {}
     
    public Animal(String name,int age){}
     
    public abstract void show();
     
    public void method() {
    System.out.println("method");
    }
    }
     
    class Dog extends Animal {
    public void show() {
    System.out.println("show Dog");
    }
    }
     
    class AbstractDemo2 {
    public static void main(String[] args) {
    //创建对象
    Animal a = new Dog();
    a.num = 100;
    System.out.println(a.num);
    //a.num2 = 200;
    System.out.println(a.num2);
    System.out.println("--------------");
    a.show();
    a.method();
    }
    }
    ==============================================
    /*
    一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
    A:可以。
    B:不让创建对象。
     
    abstract不能和哪些关键字共存?
    private 冲突
    final 冲突
    static 无意义
    */
    abstract class Fu {
    //public abstract void show();
    //非法的修饰符组合: abstract和private
    //private abstract void show();
     
    //非法的修饰符组合
    //final abstract void show();
     
    //非法的修饰符组合
    static abstract void show();
     
    public static void method() {
    System.out.println("method");
    }
    }
     
    class Zi extends Fu {
    public void show() {}
    }
     
    class AbstractDemo3 {
    public static void main(String[] args) {
    Fu.method();
    }
    }
    ==================================
    /*
    猫狗案例
    具体事物:猫,狗
    共性:姓名,年龄,吃饭
     
    分析:从具体到抽象
    猫:
    成员变量:姓名,年龄
    构造方法:无参,带参
    成员方法:吃饭(猫吃鱼)
     
    狗:
    成员变量:姓名,年龄
    构造方法:无参,带参
    成员方法:吃饭(狗吃肉)
     
    因为有共性的内容,所以就提取了一个父类。动物。
    但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的,
    而方法是抽象的类,类就必须定义为抽象类。
     
    抽象动物类:
    成员变量:姓名,年龄
    构造方法:无参,带参
    成员方法:吃饭();
     
    实现:从抽象到具体
    动物类:
    成员变量:姓名,年龄
    构造方法:无参,带参
    成员方法:吃饭();
     
    狗类:
    继承自动物类
    重写吃饭();
     
    猫类:
    继承自动物类
    重写吃饭();
    */
    //定义抽象的动物类
    abstract class Animal {
    //姓名
    private String name;
    //年龄
    private int age;
     
    public Animal() {}
     
    public Animal(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    //定义一个抽象方法
    public abstract void eat();
    }
     
    //定义具体的狗类
    class Dog extends Animal {
    public Dog() {}
     
    public Dog(String name,int age) {
    super(name,age);
    }
     
    public void eat() {
    System.out.println("狗吃肉");
    }
    }
     
    //定义具体的猫类
    class Cat extends Animal {
    public Cat() {}
     
    public Cat(String name,int age) {
    super(name,age);
    }
     
    public void eat() {
    System.out.println("猫吃鱼");
    }
    }
     
    //测试类
    class AbstractTest {
    public static void main(String[] args) {
    //测试狗类
    //具体类用法
    //方式1:
    Dog d = new Dog();
    d.setName("旺财");
    d.setAge(3);
    System.out.println(d.getName()+"---"+d.getAge());
    d.eat();
    //方式2:
    Dog d2 = new Dog("旺财",3);
    System.out.println(d2.getName()+"---"+d2.getAge());
    d2.eat();
    System.out.println("---------------------------");
     
    Animal a = new Dog();
    a.setName("旺财");
    a.setAge(3);
    System.out.println(a.getName()+"---"+a.getAge());
    a.eat();
     
    Animal a2 = new Dog("旺财",3);
    System.out.println(a2.getName()+"---"+a2.getAge());
    a2.eat();
     
    //练习:测试猫类
    }
    }
     
    ====================================================================
    /*
    老师案例
    具体事物:基础班老师,就业班老师
    共性:姓名,年龄,讲课。
     
    分析:
    基础班老师
    姓名,年龄
    讲课。
    就业班老师
    姓名,年龄
    讲课。
    实现:
    老师类
    基础班老师
    就业班老师
    */
    //定义抽象的老师类
    abstract class Teacher {
    //姓名
    private String name;
    //年龄
    private int age;
     
    public Teacher() {}
     
    public Teacher(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    //抽象方法
    public abstract void teach();
    }
     
    //基础班老师类
    class BasicTeacher extends Teacher {
    public BasicTeacher(){}
     
    public BasicTeacher(String name,int age) {
    super(name,age);
    }
     
    public void teach() {
    System.out.println("基础班老师讲解JavaSE");
    }
    }
     
    //就业班老师类
    class WorkTeacher extends Teacher {
    public WorkTeacher(){}
     
    public WorkTeacher(String name,int age) {
    super(name,age);
    }
     
    public void teach() {
    System.out.println("就业班老师讲解JavaEE");
    }
    }
     
    class AbstractTest2 {
    public static void main(String[] args) {
    //具体的类测试,自己玩
     
    //测试(多态)
    //基础班老师
    Teacher t = new BasicTeacher();
    t.setName("刘意");
    t.setAge(30);
    System.out.println(t.getName()+"---"+t.getAge());
    t.teach();
    System.out.println("--------------");
     
    t = new BasicTeacher("刘意",30);
    System.out.println(t.getName()+"---"+t.getAge());
    t.teach();
    System.out.println("--------------");
     
    //就业班老师
    t = new WorkTeacher();
    t.setName("林青霞");
    t.setAge(27);
    System.out.println(t.getName()+"---"+t.getAge());
    t.teach();
    System.out.println("--------------");
     
    t = new WorkTeacher("林青霞",27);
    System.out.println(t.getName()+"---"+t.getAge());
    t.teach();
    }
    }
    ==========================================================
    /*
    学生案例
    具体事务:基础班学员,就业班学员
    共性:姓名,年龄,班级,学习,吃饭
     
    分析:
    基础班学员
    成员变量:姓名,年龄,班级
    成员方法:学习,吃饭
    就业班学员
    成员变量:姓名,年龄,班级
    成员方法:学习,吃饭
     
    得到一个学员类。
    成员变量:姓名,年龄,班级
    成员方法:学习,吃饭
     
    实现:
    学员类
    基础班学员
    就业班学员
    */
    //定义抽象学员类
    abstract class Student {
    //姓名
    private String name;
    //年龄
    private int age;
    //班级
    private String grand;
     
    public Student() {}
     
    public Student(String name,int age,String grand) {
    this.name = name;
    this.age = age;
    this.grand = grand;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    public String getGrand() {
    return grand;
    }
     
    public void setGrand(String grand) {
    this.grand = grand;
    }
     
    //学习
    public abstract void study();
     
    //吃饭
    public void eat() {
    System.out.println("学习累了,就该吃饭");
    }
    }
     
    //具体基础班学员类
    class BasicStudent extends Student {
    public BasicStudent() {}
     
    public BasicStudent(String name,int age,String grand) {
    super(name,age,grand);
    }
     
    public void study() {
    System.out.println("基础班学员学习的是JavaSE");
    }
    }
     
    //具体就业班学员类
    class WorkStudent extends Student {
    public WorkStudent() {}
     
    public WorkStudent(String name,int age,String grand) {
    super(name,age,grand);
    }
     
    public void study() {
    System.out.println("就业班学员学习的是JavaEE");
    }
    }
     
    class AbstractTest3 {
    public static void main(String[] args) {
    //我仅仅测试基础班学员
    //按照多态的方式测试
    Student s = new BasicStudent();
    s.setName("林青霞");
    s.setAge(27);
    s.setGrand("1111");
    System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand());
    s.study();
    s.eat();
    System.out.println("--------------");
     
    s = new BasicStudent("武鑫",48,"1111");
    System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getGrand());
    s.study();
    s.eat();
     
    //就业班测试留给自己玩
    }
    }
    ====================================================================/*
    假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。
    经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
    请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
     
    分析:
    普通员工类
    成员变量:姓名、工号以及工资。
    成员方法:工作
    经理类:
    成员变量:姓名、工号以及工资,奖金属性
    成员方法:工作
     
    实现:
    员工类:
    普通员工类:
    经理类:
    */
    //定义员工类
    abstract class Employee {
    //姓名、工号以及工资
    private String name;
    private String id;
    private int salary;
     
    public Employee() {}
     
    public Employee(String name,String id,int salary) {
    this.name = name;
    this.id = id;
    this.salary = salary;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public String getId() {
    return id;
    }
     
    public void setId(String id) {
    this.id = id;
    }
     
    public int getSalary() {
    return salary;
    }
     
    public void setSalary(int salary) {
    this.salary = salary;
    }
     
    //工作
    public abstract void work();
    }
     
    //普通员工类
    class Programmer extends Employee {
    public Programmer(){}
     
    public Programmer(String name,String id,int salary) {
    super(name,id,salary);
    }
     
    public void work() {
    System.out.println("按照需求写代码");
    }
    }
     
    //经理类
    class Manager extends Employee {
    //奖金
    private int money; //bonus 奖金
     
    public Manager(){}
     
    public Manager(String name,String id,int salary,int money) {
    super(name,id,salary);
    this.money = money;
    }
     
    public void work() {
    System.out.println("跟客户谈需求");
    }
     
    public int getMoney() {
    return money;
    }
     
    public void setMoney(int money) {
    this.money = money;
    }
    }
     
    class AbstractTest4 {
    public static void main(String[] args) {
    //测试普通员工
    Employee emp = new Programmer();
    emp.setName("林青霞");
    emp.setId("czbk001");
    emp.setSalary(18000);
    System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
    emp.work();
    System.out.println("-------------");
    emp = new Programmer("林青霞","czbk001",18000);
    System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
    emp.work();
    System.out.println("-------------");
     
    /*
    emp = new Manager();
    emp.setName("刘意");
    emp.setId("czbk002");
    emp.setSalary(8000);
    emp.setMoney(2000);
    */
    //由于子类有特有的内容,所以我们用子类来测试
    Manager m = new Manager();
    m.setName("刘意");
    m.setId("czbk002");
    m.setSalary(8000);
    m.setMoney(2000);
    System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
    m.work();
    System.out.println("-------------");
     
    //通过构造方法赋值
    m = new Manager("刘意","czbk002",8000,2000);
    System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
    m.work();
    }
    }
    ====================================================================
    /*
    接口的特点:
    A:接口用关键字interface表示
    interface 接口名 {}
    B:类实现接口用implements表示
    class 类名 implements 接口名 {}
    C:接口不能实例化
    那么,接口如何实例化呢?
    按照多态的方式来实例化。
    D:接口的子类
    a:可以是抽象类。但是意义不大。
    b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
     
    由此可见:
    A:具体类多态(几乎没有)
    B:抽象类多态(常用)
    C:接口多态(最常用)
    */
    //定义动物培训接口
    interface AnimalTrain {
    public abstract void jump();
    }
     
    //抽象类实现接口
    abstract class Dog implements AnimalTrain {
    }
     
    //具体类实现接口
    class Cat implements AnimalTrain {
    public void jump() {
    System.out.println("猫可以跳高了");
    }
    }
     
    class InterfaceDemo {
    public static void main(String[] args) {
    //AnimalTrain是抽象的; 无法实例化
    //AnimalTrain at = new AnimalTrain();
    //at.jump();
     
    AnimalTrain at = new Cat();
    at.jump();
    }
    }
    ==========================================
    /*
    接口成员特点
    成员变量;只能是常量,并且是静态的。
    默认修饰符:public static final
    建议:自己手动给出。
    构造方法:接口没有构造方法。
    成员方法:只能是抽象方法。
    默认修饰符:public abstract
    建议:自己手动给出。
     
    所有的类都默认继承自一个类:Object。
    类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
    */
    interface Inter {
    public int num = 10;
    public final int num2 = 20;
    public static final int num3 = 30;
     
    //错误: 需要<标识符>
    //public Inter() {}
     
    //接口方法不能带有主体
    //public void show() {}
     
    //abstract void show(); //默认public
    public void show(); //默认abstract
    }
     
    //接口名+Impl这种格式是接口的实现类格式
    /*
    class InterImpl implements Inter {
    public InterImpl() {
    super();
    }
    }
    */
     
    class InterImpl extends Object implements Inter {
    public InterImpl() {
    super();
    }
     
    public void show() {}
    }
     
    //测试类
    class InterfaceDemo2 {
    public static void main(String[] args) {
    //创建对象
    Inter i = new InterImpl();
    System.out.println(i.num);
    System.out.println(i.num2);
    //i.num = 100;
    //i.num2 = 200;
    //System.out.println(i.num); //无法为最终变量num分配值
    //System.out.println(i.num2);//无法为最终变量num2分配值
    System.out.println(Inter.num);
    System.out.println(Inter.num2);
    System.out.println("--------------");
    }
    }
    ==========================================================
    /*
    类与类:
    继承关系,只能单继承,可以多层继承。
    类与接口:
    实现关系,可以单实现,也可以多实现。
    并且还可以在继承一个类的同时实现多个接口。
    接口与接口:
    继承关系,可以单继承,也可以多继承。
    */
    interface Father {
    public abstract void show();
    }
     
    interface Mother {
    public abstract void show2();
    }
     
    interface Sister extends Father,Mother {
     
    }
     
    //class Son implements Father,Mother //多实现
    class Son extends Object implements Father,Mother {
    public void show() {
    System.out.println("show son");
    }
     
    public void show2() {
    System.out.println("show2 son");
    }
    }
     
    class InterfaceDemo3 {
    public static void main(String[] args) {
    //创建对象
    Father f = new Son();
    f.show();
    //f.show2(); //报错
     
    Mother m = new Son();
    //m.show(); //报错
    m.show2();
    }
    }
    ====================================================================/*
    猫狗案例,加入跳高的额外功能
     
    分析:从具体到抽象
    猫:
    姓名,年龄
    吃饭,睡觉
    狗:
    姓名,年龄
    吃饭,睡觉
     
    由于有共性功能,所以,我们抽取出一个父类:
    动物:
    姓名,年龄
    吃饭();
    睡觉(){}
     
    猫:继承自动物
    狗:继承自动物
     
    跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口
    接口:
    跳高
     
    部分猫:实现跳高
    部分狗:实现跳高
    实现;
    从抽象到具体
     
    使用:
    使用具体类
    */
    //定义跳高接口
    interface Jumpping {
    //跳高功能
    public abstract void jump();
    }
     
    //定义抽象类
    abstract class Animal {
    //姓名
    private String name;
    //年龄
    private int age;
     
    public Animal() {}
     
    public Animal(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    //吃饭();
    public abstract void eat();
     
    //睡觉(){}
    public void sleep() {
    System.out.println("睡觉觉了");
    }
    }
     
    //具体猫类
    class Cat extends Animal {
    public Cat(){}
     
    public Cat(String name,int age) {
    super(name,age);
    }
     
    public void eat() {
    System.out.println("猫吃鱼");
    }
    }
     
    //具体狗类
    class Dog extends Animal {
    public Dog(){}
     
    public Dog(String name,int age) {
    super(name,age);
    }
     
    public void eat() {
    System.out.println("狗吃肉");
    }
    }
     
    //有跳高功能的猫
    class JumpCat extends Cat implements Jumpping {
    public JumpCat() {}
     
    public JumpCat(String name,int age) {
    super(name,age);
    }
     
    public void jump() {
    System.out.println("跳高猫");
    }
    }
     
    //有跳高功能的狗
    class JumpDog extends Dog implements Jumpping {
    public JumpDog() {}
     
    public JumpDog(String name,int age) {
    super(name,age);
    }
     
    public void jump() {
    System.out.println("跳高狗");
    }
    }
     
    class InterfaceTest {
    public static void main(String[] args) {
    //定义跳高猫并测试
    JumpCat jc = new JumpCat();
    jc.setName("哆啦A梦");
    jc.setAge(3);
    System.out.println(jc.getName()+"---"+jc.getAge());
    jc.eat();
    jc.sleep();
    jc.jump();
    System.out.println("-----------------");
     
    JumpCat jc2 = new JumpCat("加菲猫",2);
    System.out.println(jc2.getName()+"---"+jc2.getAge());
    jc2.eat();
    jc2.sleep();
    jc2.jump();
     
    //定义跳高狗并进行测试的事情自己完成。
    }
    }
    ===================================================================
    /*
    老师和学生案例,加入抽烟的额外功能
     
    分析:从具体到抽象
    老师:姓名,年龄,吃饭,睡觉
    学生:姓名,年龄,吃饭,睡觉
     
    由于有共性功能,我们提取出一个父类,人类。
     
    人类:
    姓名,年龄
    吃饭();
    睡觉(){}
     
    抽烟的额外功能不是人或者老师,或者学生一开始就应该具备的,所以,我们把它定义为接口
     
    抽烟接口。
     
    部分老师抽烟:实现抽烟接口
    部分学生抽烟:实现抽烟接口
     
    实现:从抽象到具体
     
    使用:具体
    */
    //定义抽烟接口
    interface Smoking {
    //抽烟的抽象方法
    public abstract void smoke();
    }
     
    //定义抽象人类
    abstract class Person {
    //姓名
    private String name;
    //年龄
    private int age;
     
    public Person() {}
     
    public Person(String name,int age) {
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    //吃饭();
    public abstract void eat();
     
    //睡觉(){}
    public void sleep() {
    System.out.println("睡觉觉了");
    }
    }
     
    //具体老师类
    class Teacher extends Person {
    public Teacher() {}
     
    public Teacher(String name,int age) {
    super(name,age);
    }
     
    public void eat() {
    System.out.println("吃大白菜");
    }
    }
     
    //具体学生类
    class Student extends Person {
    public Student() {}
     
    public Student(String name,int age) {
    super(name,age);
    }
     
    public void eat() {
    System.out.println("吃红烧肉");
    }
    }
     
    //抽烟的老师
    class SmokingTeacher extends Teacher implements Smoking {
    public SmokingTeacher() {}
     
    public SmokingTeacher(String name,int age) {
    super(name,age);
    }
     
    public void smoke() {
    System.out.println("抽烟的老师");
    }
    }
     
    //抽烟的学生
    class SmokingStudent extends Student implements Smoking {
    public SmokingStudent() {}
     
    public SmokingStudent(String name,int age) {
    super(name,age);
    }
     
    public void smoke() {
    System.out.println("抽烟的学生");
    }
    }
     
    class InterfaceTest2 {
    public static void main(String[] args) {
    //测试学生
    SmokingStudent ss = new SmokingStudent();
    ss.setName("林青霞");
    ss.setAge(27);
    System.out.println(ss.getName()+"---"+ss.getAge());
    ss.eat();
    ss.sleep();
    ss.smoke();
    System.out.println("-------------------");
     
    SmokingStudent ss2 = new SmokingStudent("刘意",30);
    System.out.println(ss2.getName()+"---"+ss2.getAge());
    ss2.eat();
    ss2.sleep();
    ss2.smoke();
     
    //测试老师留给自己练习
    }
    }
    ====================================================================抽象类和接口的区别:
    A:成员区别
    抽象类:
    成员变量:可以变量,也可以常量
    构造方法:有
    成员方法:可以抽象,也可以非抽象
    接口:
    成员变量:只可以常量
    成员方法:只可以抽象
     
    B:关系区别
    类与类
    继承,单继承
    类与接口
    实现,单实现,多实现
    接口与接口
    继承,单继承,多继承
     
    C:设计理念区别
    抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
    接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。
     
    四.匿名内部类
    package cn.itcast_03;
     
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.Scanner;
     
    /*
    * 常用快捷键
    * 1:格式化 ctrl+shift+f
    * 2:导入包 ctrl+shift+o
    * 如果该类仅仅在一个包中有,就自己显示了
    * 如果该类在多个包中有,会弹出一个框框供你选择
    * 3:注释
    * 单行:注释 ctrl+/,取消注释再来一次。
    * 多行:ctrl+shift+/,ctrl+shift+
    * 4:代码上下移动
    * 选中代码alt+上/下箭头
    * 5:查看源码
    * 选中类名(F3或者Ctrl+鼠标点击)
    */
    public class HelloWorld {
    public static void main(String[] args) {
    int a = 10;
    System.out.println(a);
     
    Scanner sc = new Scanner(System.in);
    Date d = new Date();
     
    // StringBuffer
    // ArrayList<E>
     
    Math.random();
    }
    }
    ============================================================
    package cn.itcast_03;
     
    import cn.itcast_01.HelloWorld;
     
    /*
    * alt+/ 内容辅助键
    *
    * A:main方法
    * main+alt+/ 回车即可
    * B:输出语句
    * syso+alt+/
    * C:提示作用
    * 帮助你补齐一些你你不住的东西,还可以帮你起名字等。
    */
    public class Demo {
    // public static void main(String[] args) {
    // System.out.println("HelloWorld");
    // }
     
    public static void main(String[] args) {
    System.out.println();
     
    String string = new String();
     
    HelloWorld helloWorld = new HelloWorld();
     
     
    }
    }
     
    =============================================================
    package cn.itcast_04;
     
    /*
    * 提高开发效率:
    * A:帮助我们自动提供构造方法
    a:无参构造方法
    在代码区域右键--source--Generate Constructors from Superclass
    b:带参构造方法
    在代码区域右键--source--Generate Constructors using fields.. -- finish
     
    B:成对的getXxx()和setXxx()
    在代码区域右键--source--Generate Getters and Setters...
    */
    public class Student {
    // 成员变量
    private String name;
    private int age;
     
    //构造方法
    public Student() {
    super();
    }
     
    public Student(String name, int age) {
    super();
    this.name = name;
    this.age = age;
    }
     
    //成员方法
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
     
     
    }
     
    ==========================================
    package cn.itcast_04;
     
    public class Teacher {
    // 成员变量
    private String name;
    private int age;
     
    public Teacher(String name, int age) {
    super();
    this.name = name;
    this.age = age;
    }
     
    public Teacher() {
    super();
    // TODO Auto-generated constructor stub
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    }
    =====================================
    package cn.itcast_01;
     
    public class Student {
    // 姓名
    private String name;
    // 年龄
    private int age;
     
    public Student(String name, int age) {
    super();
    this.name = name;
    this.age = age;
    }
     
    public Student() {
    super();
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    public void show() {
    System.out.println("姓名:" + name + ",年龄:" + age);
    }
    }
     
    package cn.itcast_01;
     
    /*
    * 测试类
    */
    public class StudentDemo {
    public static void main(String[] args) {
    // 创建对象
    Student s1 = new Student();
    s1.setName("风清扬");
    s1.setAge(30);
    System.out.println(s1.getName() + "---" + s1.getAge());
    s1.show();
     
    // 创建对象
    Student s2 = new Student("林青霞", 27);
    System.out.println(s2.getName() + "---" + s2.getAge());
    s2.show();
    }
    }
     
    ========================================================
    package cn.itcast_03;
     
    /*
    * 通过debug查看程序执行流程
    * 请大家也做一遍。 F6执行下一步
    */
    public class ArgsDemo {
    public static void main(String[] args) {
    int a = 10;
    int b = 20;
    System.out.println("a:" + a + ",b:" + b);
    change(a, b);
    System.out.println("a:" + a + ",b:" + b);
     
    int[] arr = { 1, 2, 3, 4, 5 };
    change(arr);
    System.out.println(arr[1]);
    }
     
    public static void change(int a, int b) {
    System.out.println("a:" + a + ",b:" + b);
    a = b;
    b = a + b;
    System.out.println("a:" + a + ",b:" + b);
    }
     
    public static void change(int[] arr) {
    for (int x = 0; x < arr.length; x++) {
    if (arr[x] % 2 == 0) {
    arr[x] *= 2;
    }
    }
    }
    }
     
    ======================================
    package cn.itcast_01;
     
    /*
    * Object:类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
    * 每个类都直接或者间接的继承自Object类。
    *
    * Object类的方法:
    * public int hashCode():返回该对象的哈希码值。
    * 注意:哈希值是根据哈希算法计算出来的一个值,这个值和地址值有关,但是不是实际地址值。
    * 你可以理解为地址值。
    *
    * public final Class getClass():返回此 Object 的运行时类
    * Class类的方法:
    * public String getName():以 String 的形式返回此 Class 对象所表示的实体
    */
    public class StudentTest {
    public static void main(String[] args) {
    Student s1 = new Student();
    System.out.println(s1.hashCode()); // 11299397
    Student s2 = new Student();
    System.out.println(s2.hashCode());// 24446859
    Student s3 = s1;
    System.out.println(s3.hashCode()); // 11299397
    System.out.println("-----------");
     
    Student s = new Student();
    Class c = s.getClass();
    String str = c.getName();
    System.out.println(str); // cn.itcast_01.Student
     
    //链式编程
    String str2 = s.getClass().getName();
    System.out.println(str2);
    }
    }
     
    ====================================================================
    package cn.itcast_02;
     
    /*
    * public String toString():返回该对象的字符串表示。
    *
    * Integer类下的一个静态方法:
    * public static String toHexString(int i):把一个整数转成一个十六进制表示的字符串
    *
    * 这个信息的组成我们讲解完毕了,但是这个信息是没有任何意义的。所以,建议所有子类都重写该方法。
    * 怎么重写呢?
    * 把该类的所有成员变量值组成返回即可。
    * 重写的最终版方案就是自动生成toString()方法。
    *
    * 注意:
    * 直接输出一个对象的名称,其实就是调用该对象的toString()方法。
    */
    public class StudentDemo {
    public static void main(String[] args) {
    Student s = new Student();
    System.out.println(s.hashCode());
    System.out.println(s.getClass().getName());
    System.out.println("--------------------");
    System.out.println(s.toString());// cn.itcast_02.Student@42552c
    System.out.println("--------------------");
    // toString()方法的值等价于它
    // getClass().getName() + '@' + Integer.toHexString(hashCode())
    // this.getClass().getName()+'@'+Integer.toHexString(this.hashCode())
     
    // cn.itcast_02.Student@42552c
    // cn.itcast_02.Student@42552c
     
    System.out.println(s.getClass().getName() + '@'
    + Integer.toHexString(s.hashCode()));
     
    System.out.println(s.toString());
     
    // 直接输出对象的名称
    System.out.println(s); // cn.itcast_02.Student@42552c
    }
    }
    ============================================================
    package cn.itcast_03;
     
    /*
    * public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。
    * 这个方法,默认情况下比较的是地址值。比较地址值一般来说意义不大,所以我们要重写该方法。
    * 怎么重写呢?
    * 一般都是用来比较对象的成员变量值是否相同。
    * 重写的代码优化:提高效率,提高程序的健壮性。
    * 最终版:
    * 其实还是自动生成。
    *
    * 看源码:
    * public boolean equals(Object obj) {
    * //this - s1
    * //obj - s2
    * return (this == obj);
    * }
    *
    * ==:
    * 基本类型:比较的就是值是否相同
    * 引用类型:比较的就是地址值是否相同
    * equals:
    * 引用类型:默认情况下,比较的是地址值。
    * 不过,我们可以根据情况自己重写该方法。一般重写都是自动生成,比较对象的成员变量值是否相同
    */
    public class StudentDemo {
    public static void main(String[] args) {
    Student s1 = new Student("林青霞", 27);
    Student s2 = new Student("林青霞", 27);
    System.out.println(s1 == s2); // false
    Student s3 = s1;
    System.out.println(s1 == s3);// true
    System.out.println("---------------");
     
    System.out.println(s1.equals(s2)); // obj = s2; //false
    System.out.println(s1.equals(s1)); // true
    System.out.println(s1.equals(s3)); // true
    Student s4 = new Student("风清扬",30);
    System.out.println(s1.equals(s4)); //false
     
    Demo d = new Demo();
    System.out.println(s1.equals(d)); //ClassCastException
     
    }
    }
     
    class Demo {}
     
     
     
     
    package cn.itcast_03;
     
    public class Student {
    private String name;
    private int age;
     
    public Student() {
    super();
    }
     
    public Student(String name, int age) {
    super();
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    @Override
    public boolean equals(Object obj) {
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    Student other = (Student) obj;
    if (age != other.age)
    return false;
    if (name == null) {
    if (other.name != null)
    return false;
    } else if (!name.equals(other.name))
    return false;
    return true;
    }
     
    // @Override
    // public boolean equals(Object obj) {
    // // return true;
    // //这里要改进,根据这里比较的成员变量来决定返回true还是false
    // //这里其实要比价的就是name和age
    // //但是,name是String类型的,而String是引用类型的,所以,在这里不能直接用==比较,应该用equals()比较
    // //String的equals()方法是重写自Object类的,比较的是字符串的内容是否相同
    // //this -- s1
    // //obj -- s2
    // //我们要使用的是学生类的特有成员变量,所以要向下转型
    // Student s = (Student)obj; //s -- obj -- s2;
    // if(this.name.equals(s.name) && this.age == s.age) {
    // return true;
    // }else {
    // return false;
    // }
    // }
     
    // @Override
    // public boolean equals(Object obj) {
    // //为了提高效率
    // if(this == obj){
    // return true;
    // }
    //
    // //为了提供程序的健壮性
    // //我先判断一下,obj是不是学生的一个对象,如果是,再做向下转型,如果不是,直接返回false。
    // //这个时候,我们要判断的是对象是否是某个类的对象?
    // //记住一个格式:对象名 instanceof 类名
    // //表示:判断该对象名是否是该类名一个对象
    // if(!(obj instanceof Student)){
    // return false;
    // }
    // //如果是就继续
    //
    // Student s = (Student)obj;
    // //System.out.println("同一个对象,还需要向下转型并比较吗?");
    // return this.name.equals(s.name) && this.age == s.age;
    // }
     
     
    }
     
    ===========================================================================
    package cn.itcast_04;
     
    *
    * Cloneable:此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。
    * 这个接口是标记接口,告诉我们实现该接口的类就可以实现对象的复制了。
    */
    public class StudentDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
    //创建学生对象
    Student s = new Student();
    s.setName("林青霞");
    s.setAge(27);
     
    //克隆学生对象
    Object obj = s.clone();
    Student s2 = (Student)obj;
    System.out.println("---------");
     
    System.out.println(s.getName()+"---"+s.getAge());
    System.out.println(s2.getName()+"---"+s2.getAge());
     
    //以前的做法
    Student s3 = s;
    System.out.println(s3.getName()+"---"+s3.getAge());
    System.out.println("---------");
     
    //其实是有区别的
    s3.setName("刘意");
    s3.setAge(30);
    System.out.println(s.getName()+"---"+s.getAge());
    System.out.println(s2.getName()+"---"+s2.getAge());
    System.out.println(s3.getName()+"---"+s3.getAge());
     
    }
    }
     
     
    package cn.itcast_04;
     
    public class Student implements Cloneable {
    private String name;
    private int age;
     
    public Student() {
    super();
    }
     
    public Student(String name, int age) {
    super();
    this.name = name;
    this.age = age;
    }
     
    public String getName() {
    return name;
    }
     
    public void setName(String name) {
    this.name = name;
    }
     
    public int getAge() {
    return age;
    }
     
    public void setAge(int age) {
    this.age = age;
    }
     
    @Override
    protected Object clone() throws CloneNotSupportedException {
    return super.clone();
    }
    }
     
    ===========================================================================
    1:Eclipse的安装
     
    2:用Eclipse写一个HelloWorld案例,最终在控制台输出你的名字
     
    A:创建项目
    B:在src目录下创建包。cn.itcast
    C:在cn.itcast包下创建类。HelloWorld
    D:在HelloWorld下有一个方法。public static void main(String[] args) {}
    E:在main方法中有一个输出语句。System.out.println("你的名字");
     
    3:Eclipse空间的基本配置
    A:程序的编译和运行的环境配置(一般不改)
    window -- Preferences -- Java
    编译环境:Compiler 默认选中的就是最高版本。
    运行环境:Installed JREs 默认会找你安装的那个JDK。建议配置了Java的环境变量。
    问题:
    低编译,高运行。可以。
    高编译,低运行。不可以。
    建议,编译和运行的版本一致。
     
    B:如何去掉默认注释?
    window -- Preferences -- Java -- Code Style -- Code Templates
    选择你不想要的内容,通过右边Edit编辑。
    注意:请只删除注释部分,不是注释部分的不要删除。
     
    C:行号的显示和隐藏
    显示:在代码区域的最左边的空白区域,右键 -- Show Line Numbers即可。
    隐藏:把上面的动作再做一次。
     
    D:字体大小及颜色
    a:Java代码区域的字体大小和颜色:
    window -- Preferences -- General -- Appearance -- Colors And Fonts -- Java修改 -- Java Edit Text Font
    b:控制台
    window -- Preferences -- General -- Appearance -- Colors And Fonts -- Debug -- Console font
    c:其他文件
    window -- Preferences -- General -- Appearance -- Colors And Fonts -- Basic -- Text Font
     
    E:窗体给弄乱了,怎么办?
    window -- Reset Perspective
     
    F:控制台找不到了,怎么办?
    Window--Show View—Console
     
    4:常用快捷键
    A:格式化 ctrl+shift+f
    B:导入包 ctrl+shift+o
    如果该类仅仅在一个包中有,就自己显示了
    如果该类在多个包中有,会弹出一个框框供你选择
    C:注释
    单行:注释 ctrl+/,取消注释再来一次。
    多行:ctrl+shift+/,ctrl+shift+
    D:代码上下移动
    选中代码alt+上/下箭头
    E:查看源码
    选中类名(F3或者Ctrl+鼠标点击)
     
    5:如何提高开发效率
    A:自动生成构造方法
    a:无参构造方法 在代码区域右键--source--Generate Constructors from Superclass
    b:带参构造方法 在代码区域右键--source--Generate Constructors using fields.. -- finish
    B:自动生成getXxx()/setXxx()方法
    在代码区域右键--source--Generate Getters and Setters...
     
    提供了对应的快捷键操作。
    alt+shift+s
    按下带有下划线的那个字母即可。
     
    C:如何继承抽象类和实现接口。
    D:Override的作用
    表示该方法是重写父类的。如果方法声明和父类不匹配,就会报错。
     
    6:通过讲解的快捷键和提高开发效率的一些内容完成如下内容
    自定义学生类:Student
    成员变量;
    姓名
    年龄
    构造方法:
    无参
    带参
    成员方法:
    getXxx()/setXxx()
    在给出一个show()方法,显示类的所有成员信息。
     
    然后,写一个测试类,对学生的代码进行测试。
    StudentDemo
     
    7:删除项目和导入项目
    删除项目
    选中项目 – 右键 – 删除
    从项目区域中删除
    从硬盘上删除
     
    导入项目
    在项目区域右键找到import
    找到General,展开,并找到
    Existing Projects into Workspace
    点击next,然后选择你要导入的项目
    注意:这里选择的是项目名称
     
    8:要注意的几个小问题
    如何查看项目所在路径
    选中 -- 右键 -- Properties -- Resource -- Location
    导入项目要注意的问题
    项目区域中不可能出现同名的项目(新建或者导入)
    自己随意建立的文件夹是不能作为项目导入的
    修改项目问题
    不要随意修改项目名称
    如果真要修改,不要忘记了配置文件.project中的
    <name>把这里改为你改后的名称</name>
     
    9:大家接收文件的注意事项
    A:专门建立一个文件夹用于接收项目,不要随意放置。
    B:同一个项目再次接收的时候,先去存放目录把原始项目删除,然后重新存储,最后刷新项目即可。
    C:每天对照我写的项目,自己也创建一个练习项目
    举例:我的项目名称 day11_eclipse
    你就创建一个项目名称 day11_eclipse_test
     
    10:Eclipse中代码的高级(Debug)调试
    作用:
    调试程序
    查看程序执行流程
     
    如何查看程序执行流程
    要想看程序流程,就必须设置断点。
     
    什么是断点:
    就是一个标记,从哪里开始。
     
    如何设置断点:
    你想看哪里的程序,你就在那个有效程序的左边双击即可。
     
    在哪里设置断点:
    哪里不会点哪里。
    目前:我们就在每个方法的第一条有效语句上都加。
     
    如何运行设置断点后的程序:
    右键 -- Debug as -- Java Application
     
    看哪些地方:
    Debug:断点测试的地方
    在这个地方,记住F6,或者点击也可以。一次看一行的执行过程。
    Variables:查看程序的变量变化
    ForDemo:被查看的源文件
    Console:控制台
     
    如何去断点:
    a:再次双击即可
    b:找到Debug视图,Variables界面,找到Breakpoints,并点击,然后看到所有的断点,最后点击那个双叉。
     
     
     
     
  • 相关阅读:
    C#获取网页内容的三种方式
    C#,COM口,接收,发送数据
    mysql查询当前正在使用数据库
    错误日志中关于innodb的问题收集
    Oracle10g下载地址--多平台下的32位和64位
    Linux-PAM认证模块
    kali安装vmware tools
    redis数据库
    mysql的innodb中事务日志ib_logfile
    MySQL数据故障时备份与恢复
  • 原文地址:https://www.cnblogs.com/yejibigdata/p/7834968.html
Copyright © 2020-2023  润新知