• Java学习笔记2(面向对象上)


    面向对象(上)

    面向对象的特点:封装性(是面向对象的核心思想,将对象的属性和行为封装起来)、继承性(主要描述类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展)和多态性(指的是在程序中允许出现重名现象,它指在一个类中定义的属性和方法被其他类继承后,它们可以具有不同的数据类型或表现出不同的行为,使得同一个属性和方法在不同的类中具有不同的语义。例如听到cut时,理发师的行为是剪发,演员的行为是停止表演)。
    一个类包含多个对象,比如动物类,包含对象有狗、狼、猫等等。
    在程序中创建对象,首先需要定义一个类。类中可以定义成员变量(用于描述对象的特征)和成员方法(用于描述对象的行为)。
    class Person{
        int age = 23;   //定义在类中的变量为成员变量
        //定义speak()方法
        void speak(){
            int age = 30;   //定义在方法中的变量为局部变量
            System.out.println("我今年"+age+"岁!");
            /*局部变量可以和成员变量同名,此时方法中通过变量名访问到的是局部变量*/
        }
    }
    class Person{
        int age;
        void speak(){
            System.out.println("我今年"+age+"岁!");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person p1 = new Person();
            Person p2 = new Person();
            p1.age = 23;
            p1.speak();
            p2.speak();
        }
    }
    运行结果
    我今年23岁!
    我今年0岁!
    注:在实例化对象时,Java虚拟机会自动为成员变量进行初始化。但是局部变量必须赋值,否则会报错。
    类的封装
    是指在定义一个类时,将类中的属性私有化,即是用private关键字来修饰,私有属性只能在它所在类中被访问。
    class Student{
        private int age;    //将age属性私有化
        private String name;    //将name属性私有化
        //下面是公有的获取属性值的getXxx()方法和设置属性值额setXxx()方法
        public String getName(){
            return name;
        }
        public void setName(String stuName){
            name = stuName;
        }
        public int getAge(){
            return age;
        }
        public void setAge(int stuAge){
            //下面对传入的参数进行检验
            if(stuAge<=0)
                System.out.println("年龄不合法...");
            else
                age = stuAge;
        }
        public void introduce(){
            System.out.println("大家好,我叫"+name+",今年"+age+"岁!");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Student stu = new Student();
            stu.setAge(-30);
            stu.setName("Payne");
            stu.introduce();
        }
    }
    运行结果
    年龄不合法...
    大家好,我叫Payne,今年0岁!
    构造方法
    构造方法的定义:必须满足以下三个条件,
    ①方法名与类名相同
    ②在方法名的前面没有返回值类型的声明
    ③在方法中不能使用return语句返回一个值
    无参的构造方法:
    class Person{
        public Person(){
            System.out.println("无参的构造方法被调用了...");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person p = new Person();    //实例化Person对象
        }
    }
    /*Person类中定义了一个无参的构造方法Person()。“new Person()”语句除了会实例化Person对象,还会调用构造方法Person()。*/
    运行结果
    无参的构造方法被调用了...
    有参的构造方法:
    class Person{
        int age;
        public Person(int a){
            age = a;    //为age属性赋值
        }
        public void speak(){
            System.out.println("I am "+age+" years old.");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person p = new Person(23);    //实例化Person对象
            p.speak();
        }
    }
    /*Person类中定义了有参的构造方法Person(int a)。“new Person(23)”会在实例化对象的同时调用有参的构造方法,并传入参数23。*/
    运行结果
    I am 23 years old.
    构造方法的重载:
    与普通方法一样,构造方法也可以重载,在一个类中可以定义多个构造方法,只要每个构造方法的参数类型或参数个数不同即可。
    class Person{
        int age;
        String name;
        //定义两个参数的构造方法
        public Person(String n,int a){
            name = n;   //为name属性赋值
            age = a;    //为age属性赋值
        }
        //定义一个参数的构造方法
        public Person(int a){
            age = a;    //为age属性赋值
        }
        public void speak(){
            System.out.println("My name is "+name+" ,"+"I am "+age+" years old.");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person p1 = new Person("Payne",23);
            Person p2 = new Person(23);
            p1.speak();
            p2.speak();
        }
    }
    /*Person类中定义了两个构造方法,它们构成了重载。*/
    运行结果
    My name is Payne ,I am 23 years old.
    My name is null ,I am 23 years old.
    注:①在Java中的每个类都至少有一个构造方法,即使没有定义构造方法,系统也会默认创建一个没有参数的构造方法。如class Person{}和class Person{public Person(){}}完全一样。
    ②当在类中定义了有参的构造方法后,在main函数里实例化对象是必须写参数,否则会报错,如在上面代码中添加“Person p3 = new Person();”后会报错。
    ③构造方法通常用public修饰,当使用private修饰时,无法在外部创建该类的实例对象。
    this关键字
    ①通过this关键字可以明确的访问成员变量,解决与局部变量的冲突问题。
    class Person{
        int age;    //定义成员变量
        public Person(int age){
            this.age = age;    //this.age代表成员变量
        }
        public int getAge(){
            return this.age;
        }
    }
    ②通过this关键字调用成员方法。
    class Person{
        public void openMounth(){
            
        }
        public void speak(){
            this.openMounth();    //调用成员方法,此处的this可以不写
        }
    }
    ③构造方法是在实例化对象时被Java虚拟机自动调用的,在程序中不能像调用其他方法一样去调用构造方法,但可以在一个构造方法中使用“this([参数1,参数2...])”的形式来调用其他的构造方法。
    class Person{
        public Person(){
            System.out.println("无参的构造方法被调用了...");
        }
        public Person(String name){
            this();     //调用无参的构造方法
            System.out.println("有参的构造方法被调用了...");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person p = new Person("Payne");
        }
    }
    运行结果
    无参的构造方法被调用了...
    有参的构造方法被调用了...
    注:只能在构造方法中使用this调用其他的构造方法,不能在成员方法中使用。②在构造方法中,用this调用构造方法的语句必须位于第一行,且只能出现一次。③不能在一个类的两个构造方法中使用this互相调用,会报错。(以上三点仅限于构造方法中使用this,成员方法不同)
    垃圾回收
    当对象设为null后,该对象就不能调用其他方法,但最后会运行System.gc();调用finalize()方法。
    class Person{
        //下面定义的finalize方法会在垃圾回收前被调用
        public void finalize(){
            System.out.println("对象将被作为垃圾回收...");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person p1 = new Person();
            Person p2 = new Person();
            //将变量设置为null,让对象成为垃圾。
            p1 = null;
            p2 = null;
            System.gc();    //调用方法进行垃圾回收
        }
    }
    运行结果
    对象将被作为垃圾回收...
    对象将被作为垃圾回收...
    public class record01 {
        public static void main(String[] args) {
            Person p1 = new Person();
            Person p2 = new Person();
            p1.getNum(5);
            p2.getNum(3);
            p1 = null;
            p2 = null;
            System.gc();
            //p1.getNum(4);    //写上这句会报错
        }
    }
    class Person{
        int i;
        public void finalize(){
            System.out.println("垃圾回收!");
            System.out.println(i);
        }
        public void getNum(int i){
            this.i = i;
            System.out.println(i);
        }
    }
    
    运行结果
    5
    3
    垃圾回收!
    5
    垃圾回收!
    3
    static关键字
    可以使用static关键字来修饰成员变量,该变量称作静态变量。静态变量被所有实例共享,可以使用“类名.变量名的形式直接访问,也可以通过类的实例对象来访问。(static只能修饰成员变量,不能修饰局部变量)
    class Person{
        static String sex;  //定义静态变量sex
    }
    public class Test {
        public static void main(String[] args) {
            Person p1 = new Person();   //创建对象p1
            Person p2 = new Person();   //创建对象p2
            Person.sex = "男";   //为静态变量赋值
            System.out.println("p1的性别是:"+p1.sex);   //打印p1的性别
            System.out.println("p2的性别是:"+p2.sex);   //打印p2的性别
        }
    }
    运行结果
    p1的性别是:男
    p2的性别是:男
    静态方法,只需要在类中定义的方法前加static关键字即可,可以实现在不创建对象的情况下调用该方法。静态方法可以使用“类名.方法名”的方式来访问,也可以通过类的实例对象来访问。
    class Person{
        //定义静态方法
        public static void sayHello(){
            System.out.println("Hello");
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person.sayHello();  //调用静态方法
        }
    }
    运行结果
    Hello
    用大括号包围起来的若干行代码称为代码块,用static关键字修饰的叫静态代码块
    class Person{
        static String country;
        //静态代码块
        static {
            country = "China";
            System.out.println("Person类中的静态代码块执行了");
        }
    }
    public class Test {
        //静态代码块
        static {
            System.out.println("测试类的静态代码块执行了");
        }
        public static void main(String[] args) {
            //下面创建了两个Person对象,静态代码块会被执行
            Person p1 = new Person();
            Person p2 = new Person();
            //由于类只加载一次,所以静态代码块只执行一次
        }
    }
    运行结果
    测试类的静态代码块执行了
    Person类中的静态代码块执行了
    单例模式
    在设计一个类时,需要保证整个程序在运行期间针对该类只存在一个实例对象。就好比月亮这个类,只存在一个。
    class Single{
        private static Single INSTANCE = new Single();  //在类的内部创建一个该类的实例对象,用静态变量INSTANCE引用该对象
        private Single(){}      //私有化构造方法,这样就不能在类的外部使用new关键字来创建实例对象了
        public static Single getInstance(){     //提供返回该对象的静态方法
            return INSTANCE;
        }
    }
    public class Test {
        public static void main(String[] args) {
            Single s1 = Single.getInstance();
            Single s2 = Single.getInstance();
            System.out.println(s1==s2);
        }
    }
    //getInstance()方法是获得Single类实例对象的唯一途径,因此Single类是一个单例的类。
    运行结果
    true
    内部类
    ①成员内部类
    class Outer{
        private int num = 23;   //定义类的成员变量
        //下面的代码定义了一个成员方法,方法中访问内部类
        public void test(){
            Inner inner = new Inner();
            inner.show();
        }
        //下面的代码定义了一个成员内部类
        class Inner{
            void show(){
                //在成员内部类的方法中访问外部类的成员变量
                System.out.println("num = "+num);
            }
        }
    }
    public class Test {
        public static void main(String[] args) {
            Outer outer = new Outer();  //创建外部类对象
            outer.test();   //调用test()方法
        }
    }
    运行结果
    num = 23
    也可以这样写,运行结果一样。(如果内部类被声明为私有时,外界将无法访问)
    class Outer{
        private int num = 23;
        class Inner{
            void show(){
                System.out.println("num = "+num);
            }
        }
    }
    public class Test {
        public static void main(String[] args) {
            //外部类名.内部类名 变量名 = new 外部类名().new 内部类名()
            Outer.Inner inner = new Outer().new Inner();//这里的new Outer()也会调用构造方法
            inner.show();
        }
    }
    ②静态内部类
    可以使用static关键字来修饰一个成员内部类,该内部类称为静态内部类,它可以在不创建外部类对象的情况下被实例化。
    class Outer{
    //这里写static可以让静态内部类调用此变量
        private static int num = 23;
        //下面的代码定义了一个静态内部类
        static class Inner{
            void show(){
                System.out.println("num = "+num);
            }
        }
    }
    public class Test {
        public static void main(String[] args) {
            //外部类名.内部类名 变量名 = new 外部类名.内部类名();
            Outer.Inner inner = new Outer.Inner();  //创建内部类对象
            inner.show();   //调用内部类方法
        }
    }
    运行结果
    num = 23
    :在静态内部类中可以定义静态成员,而在非静态的内部类中不允许定义静态的成员。下面代码是非法的:
    class Outer{
        class Inner{
            static int num = 10;    //不能定义静态成员,编译会报错
            void show(){
                System.out.println("num = "+num);
            }
        }
    }
    ③方法内部类
    方法内部类是指在成员方法中定义的类,他只能在当前方法中被使用。
    class Outer{
        private int num = 23;   //定义成员变量
        public void test(){
            //下面是在方法中定义的内部类
            class Inner{
              void show(){
                  System.out.println("num = "+num); //访问外部类的成员变量
              }
            }
            Inner inner = new Inner();     //创建内部类对象,方法内部类只能在其定义的当前方法中进行实例化
            inner.show();      //调用内部类方法
        }
    }
    public class Test {
        public static void main(String[] args) {
            Outer outer = new Outer();  //创建外部类对象
            outer.test();   //调用test()方法
        }
    }
    运行结果
    num = 23
    Java的文档注释
    /* * 开头,以*/结束。
    /**
    * @author 用于对类的说明,表示这个程序的作者。
    * @version 用于对类的说明,表示这个程序的开发版本号。
    * @param 用于对方法的说明,表示方法定义的参数以及参数对应的说明。
    * @return 用于对方法的说明,表示方法的返回值代表的意义。
    */
  • 相关阅读:
    F
    D
    J
    M
    H
    L
    Android线程之间的通讯
    Java4Android基础学习之异常
    Java4Android基础学习之接口
    Java4Android基础学习之包与访问权限
  • 原文地址:https://www.cnblogs.com/xiaochen2715/p/12012843.html
Copyright © 2020-2023  润新知