• Java基础学习笔记(四)


    21.构造方法(续):
    分类:
    隐式构造方法:如果在一个类中,没有手动编写构造方法,则系统会提供一个默认的无参的构造方法
    显式构造方法:如果在一个类中,手动编写构造方法,则系统不会提供默认的无参的构造方法

    建议:当手动编写构造方法时,建议先编写无参构造方法
    22.引用数据类型
    String
    用户自定义类型,如:Teacher、Student

    注意:引用数据类型赋值两种方式:赋值对象,赋值为null

    小知识点:当一个对象作为另一个对象的属性
    或者当一个对象中的属性是引用数据类型
    23.空指针异常
    java.lang.NullPointerException
    出现空指针异常原因:说明该引用名称中存放的不是某个对象的地址,也就是null

    解决办法:在调用某个对象中的属性或方法之前,必须保证该引用名称存放的是对象的地址

    24.封装
    24.1面向对象三大特征:封装、继承、多态
    24.2封装
    隐藏类的内部信息,不允许外部程序直接访问,而是通过方法进行操作
    24.3封装的操作步骤:
    第一步:将属性设置为私有的private,只能在本类中使用
    private int age;
    第二步:设置属性的get取值和set赋值方法
    //赋值方法
    public void setAge(int age){
    //第三步:适当位置编写判断语句
    if(age >= 0 && age <= 120){
    this.age = age;
    }else{
    this.age = 21;
    }
    }

    //取值方法
    public int getAge(){
    return age;
    }

    *
        编写人Person类,属性:名字、年龄、性别,通过封装完成对属性赋值和取值
    */
    class Person{
        //属性
        private String name;
        private int age;
        private char sex;
    
        //编写所有属性的赋值方法
        public void setName(String name){
            this.name = name;
        }
        public void setAge(int age){
            //当年龄在0---120为合法的,否则为21
            if(age >= 0 && age <= 120){
                this.age = age;
            }else{
                this.age = 21;
            }
        }
        public void setSex(char sex){
            //性别只能是男或女,否则性别为女
            if(sex == '男' || sex == '女'){
                this.sex = sex;
            }else{
                this.sex = '女';
            }
        }
        //编写所有属性的取值方法
        public String getName(){
            return name;
        }
        public int getAge(){
            return age;
        }
        public char getSex(){
            return sex;
        }
        
    }
    //编写人的测试类
    class PersonTest{
        public static void main(String[] args){
            //实例化Person
            Person p = new Person();
            
            p.setName("李四");
            p.setAge(23);
            p.setSex('n');
    
            System.out.println("姓名:" + p.getName() + "
    年龄:" + p.getAge() + "
    性别:" + p.getSex());
        }
    }


    25.this关键字
    this代表当前这个对象,也就是说当前谁调用该方法则this代表就是谁
    this关键字可以访问当前类中的属性、方法、也可以访问构造方法
    注意:

    1.当访问本类中的非静态方法和属性时,默认前面添加this.
    2.当访问本类中的构造方法时,必须编写在构造方法中,并且是第一条语句
    3.构造方法不能出现递归调用
    26.参数传递
    26.1基本数据类型作为参数传递----传递值
    总结:当基本数据类型作为参数进行传递时,传递的是值,当有一个方法中的值发生改变,则对另一个方法中的值没有任何影响(各自是独立的)


    26.2引用数据类型作为参数传递----传递地址
    总结:当引用数据类型作为参数传递时,传递的是地址,当一个方法中属性的值发生改变时,对另一个方法中的属性值有影响(共用同一个地址)

    27.static关键字
    27.1 static关键字可以修饰属性
    ---该属性在方法区中开辟空间
    ---访问时可以使用类名.属性名称、引用名称.属性名称,当引用名称的值为null时也可以访问
    如:Student.address
    stu.address
    stu = null;
    stu.address
    ---与类同生死,生命周期长
    ---类优先于对象


    27.2好处:节省空间

    27.3.3static关键字可以修饰方法
    注意:

    1.静态方法中只能访问静态属性和方法
    2.实例方法中可以访问静态的属性和方法,也可以访问实例属性和方法
    3.3static关键字可以修饰代码块 ,称为静态代码块
    static{

    }
    作用:完成静态属性赋值的

    注意:1.当类被第一次载入时,静态代码块就自动执行

    建议:当调用静态属性或静态方法时,使用类名

    练习:
    编写一个狗类,属性:名字、颜色、年龄、品种,方法:输出信息
    编写一个猫类,属性:名字、颜色、年龄,方法:输出信息
    编写测试类,分别创建猫和狗的对象,输出信息

    分析:发现以上猫类和狗类中有相同的属性、方法,能否将共有的属性和方法编写一次?
    -----能
    解决办法:
    1.将相同的属性和方法编写在单独的一个类中,称为父类
    2.然后在猫和狗子类中继承父类,并编写子类中独有的属性和独有的方法

    动物Animal类:
    共有属性:名字、颜色、年龄
    共有方法:输出信息
    狗类 继承 动物类
    独有属性:品种strain
    猫类 继承 动物类

    /第一步:编写父类Animal
    class Animal{
        //属性也叫做成员变量或实例变量
        String name;
        String color;
        int age;
    
        //方法也叫做成员方法或实例方法
        public void show(){
            System.out.println("名字:" + name);
            System.out.println("颜色: " + color);
            System.out.println("年龄:" + age);
        }
    }
    //编写狗的子类并继承父类Animal
    class Dog extends Animal{
        //编写独有的属性
        String strain;
    
        //编写show方法,输出狗的所有信息-----方法的重写
        public void show(){
            System.out.println("名字:" + name);
            System.out.println("颜色: " + color);
            System.out.println("年龄:" + age);
            System.out.println("品种:" + strain);
        }
    }
    //编写猫的子类并继承父类Animal
    class Cat extends Animal{
    
    }
    //编写测试类
    class Test{
        public static void main(String[] args){
            //创建狗的对象,输出信息
            Dog dog = new Dog();
            dog.show();  //调用子类中重写后的show方法
    
            System.out.println();
            //创建猫的对象,输出信息
            Cat cat = new Cat();
            cat.show();  //调用父类中的show方法
        }
    }



    28.继承
    28.1好处:减少代码的冗余性
    28.2面向对象有三大特征:封装,继承,多态

    28.3继承画类图


    28.4编写继承的代码
    第一步:编写父类
    第二步:编写子类
    class 子类名称 extends 父类名称{

    }

    注意:在Java中,所有类都是从Object类继承过来的,也就是说所有类的根都是Object
    class Dog{

    }
    //等价于
    class Dog extends Object{

    }

    也就是说如果父类是Object则可以省略不写
    28.5 方法重写(override)也叫覆盖
    在子类中重写父类中的方法,必须保证子类中方法的名字与父类方法名称一致、参数列表一致、返回一致或父类方法返回类型的子类类型、修饰符不能缩小范围

    注意:

    1.只能重写父类的实例方法
    2.私有的方法不能被重写
    2.继承的注意事项
    ---当子类继承父类时,继承父类中属性和方法,但是父类中的私有成员(成员变量和成员方法)不能被继承,以及父类中的构造方法也不能被继承
    ---父类也叫做超类,基类
    子类也叫做派生类
    ---一个类只能继承一个直接的父类,也就是说类是单根性
    ---类具有传递性
    class A{
    //2个属性,3个方法
    }
    class B extends A{
    //独有属性1个,独有方法2个
    }
    class C extends B{

    }
    28.6.super关键字
    super表示父类,必须在子类中访问父类中的属性、方法也可以访问父类中的构造方法
    注意:当使用super关键字访问父类中的构造方法,则必须编写在子类构造方法中,并且是第一条语句

    .this关键字
    this关键字可以访问当前类中的属性、方法以及构造方法
    还可以访问父类中的属性、方法

    28.7.当创建子类对象,父类做了什么?
    ----先执行父类的构造方法,然后再执行子类相匹配的构造方法

    ----如果子类构造方法中没有指明调用父类哪个构造方法,则默认调用父类的无参构造方法
    ----如果子类构造方法中指明调用父类哪个构造方法,通过super()或super(name,color,age),则调用父类相匹配的构造方法
    29.多态

    多个对象调用同一个方法,则结果不同

    class Person{
        //属性
        String name;
        int age;
        char sex;
    
        //构造方法
        public Person(){
    
        }
        public Person(String name,int age,char sex){
            this.name = name;
            this.age = age;
            this.sex = sex;
        }
    
        //编写显示信息方法
        public void show(){
            System.out.println("姓名:" + this.name + "
    年龄:" + this.age + "
    性别:" + this.sex);
        }
    }
    //编写Student子类并继承Person父类
    class Student extends Person{
        //编写子类独有的属性:成绩
        double score;
    
        //构造方法
        public Student(){
    
        }
        public Student(String name,int age,char sex,double score){
            super(name,age,sex);
            this.score = score;
        }
    
        //编写学习的独有方法
        public void study(){
            System.out.println(super.name + "正在学习面向对象编程......");
        }
    
        //重写显示信息方法
        public void show(){
            super.show();
            System.out.println("成绩: " + score);
        }
    }
    //编写Teacher子类并继承Person父类
    class Teacher extends Person{
        //编写独有属性:薪资
        double salary;
    
        //构造方法
        public Teacher(){
    
        }
        public Teacher(String name,int age,char sex,double salary){
            super(name,age,sex);
            this.salary = salary;
        }
    
        //编写独有方法教学
        public void teach(){
            System.out.println(super.name + "正在讲面向对象编程课程。。。。。。");
        }
    
        //重写父类的显示信息方法
        public void show(){
            super.show();
            System.out.println("薪资:" + this.salary);
        }
    }
    //编写测试类
    class Test{
        public static void main(String[] args){
            //创建Student对象
            /*Student s = new Student();  //没有构成多态
            s.show();  //先在学生类中找,如果没有找到则再去父类中找show方法*/
    
            /*Person s2 = new Student();  //就是多态:多种形态,则只能访问父类中的属性和方法,但是优先访问子类重写以后的方法
            s2.show();  //优先访问子类重写以后的方法
            //s2.study();  //出现编译错误,原因:多态不能访问子类独有的属性和方法
    
            System.out.println(s2.name);  //null
            System.out.println(s2.age);  //0
            System.out.println(s2.sex); //
            //System.out.println(s2.score);  //出现编译错误,原因:多态不能访问子类独有的属性和方法*/
    
            //父类类名 引用名称 = new 子类类名();
            /*Person p = new Student();  //构成多态
            p.show();  //优先访问重写以后的方法
    
            System.out.println();
            Person p2 = new Teacher();  //构成多态
            p2.show();*/
    
            /*Teacher t = new Teacher();  //没有构成多态
            t.show();*/
        }
    }
    
    //编写第二个测试类
    class Test2{
        public static void main(String[] args){
            //Student s = new Student();  //没有构成多态
            /*System.out.println(s.name);  //null
            System.out.println(s.age);  //0
            System.out.println(s.sex); 
            System.out.println(s.score);  //0.0
    
            s.show();
            s.study();*/
    
            Person p = new Person(); //没有构成多态,注意:一般不实例化父类
            /*System.out.println(p.name);  //null
            System.out.println(p.age); //0
            System.out.println(p.sex); */
            //System.out.println(p.score); //编译错误
    
            //p.show();  //访问父类中的show方法
    
            Person person = new Student();  //构成多态,同时也是向上转型
            person.show();
            
            //必须将person引用名称转为Student类型,则才可以访问study方法
            //person.study(); //编译错误
            /*Student stu = (Student)person;  //向下转型
            stu.study();
    
            Teacher t = (Teacher)person;  //出现运行错误,原因:person引用中存放的是学生对象的地址,因此不能随意转为其他子类类型,建议在进行向下转型之前先进行判断,当合法进行向下转型,使用instanceof关键字
            System.out.println(t.salary);*/
    
            //在进行向下类型转换时可能会出现类型转换异常(java.lang.ClassCastException),进行判断
            if(person instanceof Student){
                //则强制转为学生
                Student s = (Student)person;
                s.study();
            }else if(person instanceof Teacher){
                //则强制转为教师
                Teacher t = (Teacher)person;
                t.teach();
            }
        }
    }


    29.1语法格式:
    父类类名 引用名称 = new 子类类名(); //当构成多态时,只能访问父类中的属性和方法,但是优先访问子类重写以后的方法
    29.2满足多态的条件:
    1.必须子类继承父类
    2.必须在子类中重写父类的方法
    3.父类类名 引用名称 = new 子类类名();
    6.3在多态中,有两种类型转换:
    1.子类对象---->父类类型,称为向上转型或自动类型转换
    如:Person p = new Student(); //构成多态,也是向上转型或自动类型转换

    举个例子:有2个类,Father是父类,Son类继承自Father。

    Father f1 = new Son();   // 这就叫 upcasting (向上转型)

    // 现在f1引用指向一个Son对象

    Son s1 = (Son)f1;   // 这就叫 downcasting (向下转型)


    当是向上转型时则只能访问父类中的属性和方法,但是优先访问子类重写以后的方法
    2.父类引用名称---->子类类型,称为向下转型或强制类型转换
    Student p = (Student)p;
    *****注意:

    1.当是多态时,并访问子类独有的属性或方法时则必须进行向下转型
    2.在进行向下类型转换时可能会出现类型转换异常(java.lang.ClassCastException),建议先进行判断,满足在进行强制类型转换
    30.递归:方法自己调用自己,但是必须保证要有出口
    练习:使用递归完成计算n!,如:3!= 3 * 2 * 1

  • 相关阅读:
    Pyramid of Glasses(递推)
    Vasya and String(尺取法)
    10317 Fans of Footbal Teams(并查集)
    8633 回文划分(dp)
    bzoj1036
    POJ 3071 Football(概率DP)
    POJ A Plug for UNIX (最大流 建图)
    hdu 3060 Area2 (计算几何模板)
    POJ 1273 Drainage Ditches (网络流Dinic模板)
    POJ 2443 Set Operation (按位压缩)
  • 原文地址:https://www.cnblogs.com/kosinggit/p/8783470.html
Copyright © 2020-2023  润新知