面向对象(上)

面向对象的特点:封装性(是面向对象的核心思想,将对象的属性和行为封装起来)、继承性(主要描述类与类之间的关系,通过继承,可以在无需重新编写原有类的情况下,对原有类的功能进行扩展)和多态性(指的是在程序中允许出现重名现象,它指在一个类中定义的属性和方法被其他类继承后,它们可以具有不同的数据类型或表现出不同的行为,使得同一个属性和方法在不同的类中具有不同的语义。例如听到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,成员方法不同)
垃圾回收
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();    //调用方法进行垃圾回收
    }
}
运行结果
对象将被作为垃圾回收...
对象将被作为垃圾回收...
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 用于对方法的说明,表示方法的返回值代表的意义。
*/

Java学习笔记(面向对象上)的更多相关文章

  1. 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用

    垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...

  2. 0028 Java学习笔记-面向对象-Lambda表达式

    匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...

  3. 0025 Java学习笔记-面向对象-final修饰符、不可变类

    final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...

  4. 0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类

    static可以修饰哪些成员 成员变量---可以修饰 构造方法---不可以 方法---可以修饰 初始化块---可以修饰 内部类(包括接口.枚举)---可以修饰 总的来说:静态成员不能访问非静态成员 静 ...

  5. 程序设计基础·Java学习笔记·面向对象(下)

    Java程序设计基础之面向对象(下) (补充了上的一些遗漏的知识,同时加入了自己的笔记的ヾ(•ω•`)o) (至于为什么分P,啊大概是为了自己查笔记方便(?)应该是("` 3′") ...

  6. 程序设计基础·Java学习笔记·面向对象(上)

    Java程序设计基础之面向对象(上) (自适应学习进度而进行记录的笔记,希望有一些小小的用处吧(^∀^●)ノシ) (新人上路,望多指教,如有错误,望指正,万分感谢(o゚v゚)ノ) 目录 一.面向对象 ...

  7. 0029 Java学习笔记-面向对象-枚举类

    可以创建几个对象? n多个:大部分的类,都可以随意创建对象,只要内存不爆掉 1个:比如单例类 有限的几个:采用单例类的设计思路,可以只允许创建少数的几个特定的对象:还有就是枚举类. 创建少数几个对象, ...

  8. 0021 Java学习笔记-面向对象-包、构造器

    封装 面向对象的三大特征: 封装 继承 多态 封装: 将对象的状态信息隐藏,不允许外部程序直接访问 通过该类提供的方法来访问和操作 有啥用: 隐藏类的实现细节 在方法中加入控制逻辑,限制对成员变量的不 ...

  9. 0019 Java学习笔记-面向对象-方法

    方法属于谁 方法要么属于类,要么属于对象 static修饰的方法属于类 没有static修饰的方法属于对象 方法只能定义在类里面,不能独立定义 不能独立的执行方法,要么通过类调用,要么通过方法调用 一 ...

  10. java学习笔记 --- 面向对象2

    一.匿名对象 (1)没有名字的对象 (2)应用场景   A:调用方法,仅仅只调用一次的时候. class Car { //描述属性.颜色,轮胎数. String color; int number; ...

随机推荐

  1. JDBC向数据库中写数据

    package MYSQK; import java.sql.*; /** * PreparedStatement 对象可以对sql语句进行预编译,预编译的信息会存在存储该对象中,当相同的sql语句再 ...

  2. CSPS模拟 85

    WWB大佬的bitset映射真是太强了! %%% T1 观察样例,猜规律. T2 对题目的翻译工作用了很长时间 翻译错了好几次.. 观察到奇环没法染色,选的边必须把奇环弄断 如果在偶环上,偶环就变得没 ...

  3. js 重写a标签的href属性和onclick事件

    适应场景:假如移动端拨打电话,需要给a标签添加href属性,但是由于需求,需要链接跳转的同时给a标签添加onclick事件,如果不做任何处理的话,默认执行点击事件,而不会跳转href属性的链接. 怎么 ...

  4. 大数据之路day04_2--经典bug(equals与==比较不同,break的跳出不同)

    一.equals与==比较不同 在实现某个人去5个商场去购物,控制台输入是否购物(Y/N)的时候,在比较出了问题,发现无论输入什么都是false,后来查阅资料发现,字符串的比较,==和equals不一 ...

  5. 使用springcloud开发测试问题总结

    使用springcloud开发测试 如下描述的问题,没有指明是linux部署的,都是在windows开发环境上部署验证发现的. Issue1配置客户端不使用配置中心 问题描述: 配置客户端使用配置中心 ...

  6. 文件输入输出函数fgetc/fputc及fgets/fputs等文件指针位置的变化

    文件打开后才可以对文件进行操作.也就是说,文件必须经历打开-操作-关闭的过程.如前所述,C语言对文件的操作都是通过调用标准I/O库函数来实现的.文件操作实际是指对文件的读写.文件的读操作就是从文件中读 ...

  7. 小白历险记:spingboot之helloworld

    还记得入职第一天的时候,先安装了相关的软件,配置了环境.boss叫我写的第一个程序:搭建一个springboot工程,输出helloworld. 哈哈话不多说,回忆一下. 1.打开IDEA,点击Cre ...

  8. 使用Rider中搭建specflow+xunit+selenium对web页面进行自动化功能测试环境

    运行rider,创建测试解决方案,选择xunit,点击create创建 ​   导入包,由于本人使用chrome浏览器(需先下载好对应的浏览器驱动),所以导入了selenium.webdriver.c ...

  9. Batch批处理获取当前时间

    这不是一个新问题,但是由于网上写的都是针对自己的电脑设置,没有通用性,而我呢,又需要在不同电脑上使用,因此,这命题一个问题了.其实也没有什么好说的,直接上代码. @ECHO OFF set split ...

  10. [笔记]IDEA使用笔记

    1.IDEA的目录结构 2.所有的源文件都必须写在src文件夹下, 3.输入psvm再按回车,就会生成主函数: 4.输入sout就会生成输出语句的格式: 5.ALT+4   调出上次运行的结果出来看看 ...