第五章-------面向对象

技能目标:

1.掌握类的定义和对象的创建

2.掌握方法及方法重载

3.掌握构造方法及重载

4.理解封装的原理

5.掌握包的使用

6.会使用访问修饰符

7.会使用方法重载

5.1.1面向对象的基本概念

1.面向对象

Java语言是一种面向对象的语言。要使用Java进行面向对象的编程,首先要建立面向对象的思想。面向对象是一种直观而且程序结构简单的程序设计方法,它比较符合人类认识现实世界的思维方式。其基本思想是把问题看成若干个对象组成,这些对象之间是独立的,但又可以相互配合连接和协调,从而共同完成整个程序要实现的任务和功能。

面向对象的三大特征:封装、继承、多态

2.对象

对象是用来描述客观事物的一个实体。用面向对象的方法解决问题,要对现实世界中的对象进行分析与归纳,找出哪些对象与要解决的问题是关联的。例:奥迪跑车、宝马跑车、奔驰轿车、保时捷跑车,虽然这几个跑车都是对象,但是他们之间具有不同的特征。具体来讲就是品牌不同、价格不同、性能不同等。

3.类

刚才的几个跑车对象之间具有一些共同的特征,如都有轮子、门等:还有一些共同的行为,即能发动,能加速,能制动等,把这些共同的特征和共同的行为组织到一个单元中,就得到类

类是具有相同属性和方法的一组对象的集合。类定义了对象将会拥有的特征(属性)和行为(方法)。

类与对象的关系就如同模具和用整个模具制作出的物品之间的关系。一个类给出它的全部对象的一个统一的定义,而它的每个对象则是符合这种定义的一个实体。因此类和对象的关系就是抽象和具体的关系。类是多个对象进行综合的抽象的结果,是实体对象的概念模型,而一个对象是一个类的实例。  如:我我定义一个人类,他(她)的属性有身高,年龄,体重。我在定义方法,他在哪里上学.   (后文解释)

第一个例子:后文陆续以此例子来解释

建一个类:人类Person(首字母大写)

public class Person {
    public String name;                     //姓名属性
    public int age;                         //年龄属性
    public int peso;                        //体重属性
    public  void output (){                 //定义一个方法输出
        System.out.println("姓名:"+name+" 年龄:"+age+" 体重:"+peso);
    }

    public void school(String school){      //一个学校方法
        System.out.println(name+"的学校是:"+school);
    }

}

建一个对象(实例化)

public class Text1 {
    public static void main(String[] args) {
        Person person1=new Person();//对象名为person1,也就是实例了
        person1.name="小明";
        person1.age=19;
        person1.peso=88;
        person1.output();
        person1.school("合肥十中");
    }
}



结果:

姓名:小明 年龄:19 体重:88
小明的学校是:合肥十中

5.1.2定义类

面向对象设计的过程就是抽象的过程,一般分为3步来完成。

(1).发现类,类定义了对象将会拥有的特征(属性)和行为(方法)

​ (2).发现类的属性,对象所拥有的静态特征在类中表示时称为类的属性

(3).发现类的方法,对象执行的操作称为类的方法

1.定义类

首先定义“人” 的类

定义类的语法格式如下。

[访问修饰符] class 类名{

//省略类的内部具体的代码

}

1).访问修饰符如public、private、等是可选的,其具体含义后续详讲

2).class声明类的关键字

3).按照命名规范,类名首字母大写

示例1:

定义一个“人”类。

2.属性

Java中的类的内部主要包含属性和方法。对象所拥有的特征在类中表示时称为类的属性。

定义属性的语法格式如下。

[访问修饰符] 数据类型 属性名:

1.访问修饰符是可以选的

2.除了访问修饰符之外,其他的语法和声明变量类似

属性在测试类中赋值

Person person1=new Person();
        person1.name="小明";
        person1.age=19;
        person1.peso=88;

------------------------

输出可以直接用
System.out.println(person1.age);
也可以用调用person1.output();方法

示例2:

创建“人”类,并为“人”类田间相应的属性

分析如下:

人都有姓名,体重和年龄,因此这3个特征就可以称为“人”类的属性

(如上图)

3.方法

对象执行操作的行为称为类的方法,例如,除了上个例子的学校

人还有有工作的行为,因此“工作”就是“人”类的一个方法

“人”类还有很多方法,如吃、喝、睡觉等

定义方法的语法格式:

[访问修饰符] 返回类型 方法名称(参数类型 参数名1,参数类型 参数名2,...){

//...省略方法体代码

}

1)访问修饰符是可选的

2)返回类型可以是void,在定义方法时,返回类型为void时标明没有返回值,方法体中不必使用"return"

关键字返回具体数据,但是可以使用"return"关键字退出方法

3)返回类型如果不是void,那么在方法体中一定使用“return”关键字返回对应类型的结果,否则程序会

出现编译错误。

4)当需要在方法执行的时候为方法传递参数时才需要参数传递列表,如果不需要传递参数就可以省略,

不过小括号不可以省略,传递多个参数时以半角的逗号进行分隔(参数放小括号里)

如:第一个例子中output方法是无参的我只需要用来输出

school传递了一个学校,我需要他来告诉我小明的学校是什么。

5.1.3创建和使用对象

1.创建对象

类是一个事物的集合和抽象,代表这类事物共有的属性和行为,一个对象称为类的一个实例,是类一次实例化的结果,例如,“person1”是一个“人”类的具体对象(可以设为任意)

类的对象可以调用类中的成员,如属性和方法等

创建对象的语法格式:

类名 对象名 =new 类名()

1).new是关键字

2).左边的类名为对象的数据类型

3).右边的类名()称为类的构造方法(后面会学习)

结合第一个例子来理解

第一个例子中代码表示创建了Person类的一个对象,对象名是person1,Person是一个"人"类,而person1只是Person类的一个对象实例。

2.使用Java对象

在Java中,要引用对象的属性和方法,需要使用"."。(点)

使用Java对象的语法格式:

对象名.属性 //引用对象的属性

对象名.方法名() //引用对象的方法

创建对象后,用点可以看到所有的方法和属性

 

面向对象的优点如下几点:

1).与人类的思维习惯一致:面向对象的思维方式是从人类考虑问题的角度出发,把人类解决问题的思维过程转变为程序能够理解的过程、面向对象程序设计使用"类"来模拟现实世界中的抽象概念,用"对象"来模拟现实世界的实体从而用计算机解决现实问题

2)信息隐藏,提高了程序的可维护性和安全性:封装实现了模块化和信息隐藏,即将类的属性和行为封装在类中,这保证了对他们的修改不会影响到其他对象,利于维护。同时,封装使的在对象外部不能随意访问对象的属性和方法,避免了外部错误对它影响,提高了安全性

3)提高了程序的可重用性:一个类可以创建多个对象实例,体现了重用性。(创建多个对象是不能重名)

3.对象数组

需求:

定义包含3个元素的对象数组,数据类型为Person,并使用for循环遍历

5.2.1成员方法

类成员主要包含两部分:成员方法和成员变量(可以理解为属性)

1.带参数的方法

在实际应用中经常使用带参数或有返回值的方法

2.无参的方法

3.有返回值

public class Student {
    public String name;

    public void work(){
        System.out.println("好好学习");
    }
    public void work(String why){
        System.out.println(why+"好好学习");
    }
    public String works(){
        return "能赚钱好好学习";
    }
}
public class Text3 {
    public static void main(String[] args) {
        Student student=new Student();
        student.name="小李";
        student.work();
        student.work("为了赚钱");
         String works = student.works();
        System.out.println(works);
    }
}




结果:
好好学习
为了赚钱好好学习
能赚钱好好学习

有参就在多定义了一个变量,在你调用方法时可以控制

有返回值方法在调用是会把return的值返回过来.这里定义了一个works来接受

2.方法重载:

(1)方法重载的定义

方法重载是指一个类中定义多个同名的方法,但要求每个方法具有不同的参数类型或参数个数。

示例10:

需求:

定义一个不带参数的work()的方法,再定义一个带参数的work()方法,然后观察二者之间的区别

你调用work()时,括号不输入,则调用无参的方法,输入一个参调用一个参数的方法,

同理你如果定义了两个参数的方法,你调用work()时,在括号里输入两个参即可。

2)方法重载的特点:

1.在同一个类中

2.方法名相同

3.参数个数或类型不同

4.方法的返回值不能作为判断方法之间是否构成重载的依据

(3)方法重载的使用

方法重载定义后,通过对象调用时该如何选择?

(4)方法的重载的优点

方法重载其实是对原有的方法的一种升级,可以根据参数的不同,采用不同的实现方法,而且不需要编写多个名称,简化了类调用方法的代码

5.2.2成员变量

1.成员变量作用域

类中的属性,也就是直接在类中定义的变量称作成员变量,它定义在方法的外部。

在下面的代码中Student类中的name也不属于work()方法,而属于

Student类本身的属性,他们是Student类的成员变量

public class Student {
    public String name;

    public void work(){
        String name="力王";
        System.out.println("好好学习");
    }

注意:

成员变量可以在声明时赋初始值。

分析:

work()方法中的变量name就是局部变量

注意:

虽然成员变量name和局部变量name的名称一样,但表示的却不是同一个变量,一般情况下,局部变量,在使用前需要赋值,否则会编译出错。局部变量在哪定义在哪使用

3.成员变量和局部变量的区别

使用成员变量和局部变量时需要注意如下几点:

(1).作用域不同。局部变量的作用域仅限于定义它的方法,在该方法外无法访问它。成员变量的作用域在整个类内部都是可见的,所有的成员方法都可以使用它,如果访问权限允许,还可以在类外部使用成员变量

(2).初始值不同,对于成员变量,如果在类定义中没有给它赋予初始值,Java会给它一个默认值,基本数据类型的值为0,引用类型的值为null,但是Java不会给局部变量赋予初始值,因此局部变量必须要定义并赋值后使用

(3)在同一个方法中,不允许有同名的局部变量。在不同的方法中,可以有同名的局部变量

(4)局部变量可以和成员变量名同名(可以使用this关键字来指代成员变量,下文介绍),并且一起使用,局部变量有更高的优先级

4.数据类型:

在Java中,变量的类型分为两种:一种是基本数据类型,一种是引用数据类型

Java中的引用数据类型包括3种:类、数组、接口

分析如下:

int为基本数据类型,当初始化num1并赋值后,将num1赋给num2,然后修改num2的值,运行后发现num1的值没有改变。

class为引用数据类型,当实例化person1对象并对其属性赋值后,将person1对象赋给person2对象,然后修改person2的值,运行后发现person1的属性值发生变化。

几乎同样的操作,为什么会有完全相反的结果?这是因为int和class在内存种的存储方式不同,这也是基本数据类型和引用数据类型的主要区别。

对于基本数据类型,不同的变量会分配不同的存储空间,并且存储空间中存储的是该变量的值,赋值操作传递的是变量的值,改变一个变量的值不会影响另外一个变量的值

对于引用数据类型,赋值是把原对象的引用(可以理解内存地址)传递给另外一个引用,对数组而言,当用一个数组名直接给另一个数组赋值时,相当于传递一个引用,此时,这两个引用指向同一个数组,也就是指向同一内存空间

注意: String属于引用数据类型,但String创建对象初始化后(字符串是常量),不可改变,String类的任何改变,都是返回一个新的String类对象。地址不会改变。

6.2.3构造方法

Java中,当类创建一个对象时会自动调用该类的构造方法,构造方法分为默认构造方法和带参数的构造方法

1.构造方法的定义

构造方法的主要作用是进行一些数据的初始化

定义构造方法的语法格式如下。

【访问修饰符】 方法名(【参数列表】){

//省略方法体的代码

}

1).构造方法没有返回值

2).默认构造方法没有参数,因此参数列表可选

3).构造方法的方法名与类名相同

public class Student1 {
    String name;

    public void getname(){
        System.out.println(name);
    }
    public Student1(){
        this.name="小白";
    }
}

public class Text4 {
    public static void main(String[] args) {
        Student1 student1=new Student1();
        student1.getname();

    }
}

结果为:小白

我没有给name,他的默认值从null变为了小白,这就是构造方法的用途:初始化。

注意:

如果自定义一个或多个构造方法,则Java不会自动添加默认构造方法

2.构造方法重载

构造方法也可以重载,即在同一个类中可以定义多个重载的构造方法。

分析:

在成员变量的示例中多次用到了this关键字,this的含义是什么呢?

this关键字是对一个对象的默认引用,每个实例方法内部都有一个this引用变量,指向调用这个方法的对象,其实就是指当前对象的引用,通俗点理解本对象自己

this使用举例如下:

this.属性名:

表示本对象自己的属性使用this调用成员变量,解决变量和局部变量的同名冲突

public class Student1 {
    String name;

    public void what(){
        String name="小李";
        System.out.println(this.name+"下课邀请"+name+"玩游戏");
    }
}

ublic class Text5 {
    public static void main(String[] args) {
        Student1 student1=new Student1();
        student1.name="小明";
        student1.what();
    }
}


结果:
小明下课邀请小李玩游戏

分析:

很明显this.name为类的name也就是成员变量。如果没有this关键字,则name优先指方法里的小李。

通过程序的运行结果我们可以看出,在创建对象的时候,对象的属性被赋予了正确初始值。这个程序本身非常的简单,谁都可以理解,但是大家请注意,我们在定义构造方法的时候,把表示姓名、年龄和身高的参数分别命名为:n、a和h,这种命名的可读性有点差,为了提高可读性,我们把构造方法的参数名称修改为name、age和height,用this区分即可

示例:

  public Person(String name,int age,double height){
        name=name;
        age=age;
        height=height;
        
    }
结果:

我叫null,今年0岁

Process finished with exit code 0
null和0都是数据初始化的值

分析:

同名情况下,局部变量的优先级更高”原则 

在构造方法执行的过程中,虚拟机会把参数值赋给”参数本身”,而不是赋值给对象的属性!

public Person(String name,int age,double height){
        this.name=name;
        this.age=age;
        this.height=height;
    }

修改成这样即可。

(2)this.方法名:

表示本对象自己的方法

我们给Person类增加了一个”打招呼”的方法叫做greet。在introduce方法当中,就可以通过”this.方法名”的方式来调用这个方法,表示调用的是”本对象自己的greet”方法。这是this关键字的第二种用法。当然,在introduce方法中并没有出现其他对象,所以方法名前面的this关键字也可以省略不写。

public class Student1 {
    String name;
public void greet(){
        System.out.println("hello,大家好");
    }
public void introduce(){
        this.greet();
        System.out.println("我叫"+name);
    }
}

public class Text5 {
    public static void main(String[] args) {
        Student1 student1=new Student1();
        student1.name="小明";
        student1.introduce();
    }
}



结果:hello,大家好
我叫小明

(3)this关键字3

还有另外一种很重要的用法,那就是在this关键字的后面加上小括号,这样就表示调用了某个类自身的构造方法,为了讲解这种用法我们再来修改一下Person类:

我们给Person类又增加了一个构造方法。这个构造方法只有2个参数,并且只初始化2个属性。为了讲述方便,我们把上面的3个参数的构造方法称之为”构造方法①”,把下面的2个参数的构造方法称之为”构造方法②”。通过观察不难发现,这两个构造方法当中前2行代码是相互重复的,为了避免这种重复性的代码出现,我们可以在”构造方法①”当中调用”构造方法②”。调用的方式如下:

 //构造方法1
    public Person(String name,int age,double height){
        this(name,age); //调用构造方法2
        this.height=height;
    }
    
     //构造方法2
    public Person(String name,int age){

        this.name=name;
        this.age=age;
    }

在”构造方法①”中,通过”this(参数);”的方式调用了”构造方法②”。这就是this关键字的又一种用法。很多同学可能不理解,为什么要通过这种方式来调用构造方法呢?我们难道不能直接写一个”Person(name,age);”来调用吗?这里必须做出解释:在Java语言中,一个类的构造方法与类名相同。但是,一个类当中也可以定义一个与类名相同的”普通方法”,换句话说就是:并不是只有构造方法与类名相同,”普通方法”也可以取和类相同的名称(只不过全世界的程序员都不会这么干)。那么,在这种情况下,编译器如何区分这个方法是”普通方法”还是”构造方法”呢?很简单,”普通方法”的名称前面必须定义返回值类型,而”构造方法”的名称前面则没有返回值类型的定义。这样,编译器就能够分得清哪个是”构造方法”,哪个是”和类同名的普通方法”。

定义的时候分得清,但是在调用的时候,都是通过方法名来调用的,这时如何分得清代码中哪一句调用的是”构造方法”, 哪一句调用的是”和类同名的普通方法”呢?为了解决这个问题,Java语言规定,在本类中调用构造方法的时候,需要通过”this(参数)”的方式来调用。除此之外,Java语言还规定了这种调用方式所必须遵守的规则。首先,这种”this(参数)”的方式只能在”其他构造方法中”使用,不能在普通方法中用。如果在普通方法中按这种方式使用,将被视为语法错误,如下代码:

 public void greet(){
        this("张三",20);//此处代码错误,不能在普通方法中调用
        System.out.println("hello,大家好");
    }

注意:

构造方法①中调用了构造方法②,并没有出现new关键字,调用构造方法②仅仅是完成了name和age这两个属性的初始化,并不会创建出两个对象。

我们要思考的第二个问题是:既然Java语言允许”普通方法”的名称与类名相同,而构造方法也与类名相同,那么在Person以外的类当中如果写上了”Person(参数)”这样的代码,虚拟机如何判断所调用的是普通方法还是构造方法呢?答案也很简单,如果”Person(参数)”的前面出现了new关键字,这就说明调用的是构造方法,否则说明调用的是普通方法。

(4).外部类名.this.属性

this关键字在我们编写内部类代码的时候,还有一种用途,那就是区分属性或方法的具体归属

public class Outter {                                    //定义一个外部类
    int a;
    class Intter{                                        //定义一个内部类
        public void output(){
            System.out.println(a);
        }
    }
    public Outter(int a){                                //给a给个初值
        this.a=a;
    }
}


public class Text7 {
    public static void main(String[] args) {            
        Outter outter=new Outter(6);
        Outter.Intter intter=outter.new Intter();        //实例一个内部类 intter
        intter.output();
    }
        }

结果:6

分析:

在这段代码中,定义了外部类Outter,Outter有一个属性a,并且Outter中又定义了内部类,在内部类的printA()方法中调用了外部类的a属性。我们都知道,一个内部类可以直接访问它所在外部类的属性和方法。这个特性在我们的上面这段代码中得到了体现。但是,如果内部类中出现了与外部类同名的属性或方法时,该如何区分调用的到底是哪个属性或方法呢?比如说,在Inner类中也出现了a属性,那么输出语句中的a到底是指哪个a呢?很简单,如果输出语句中直接写a,那么调用的是内部类的a属性。为了强调它是内部类的a属性,我们也可以在a的前面加this关键字。如果我们希望调用的是外部类的a属性,可以用”外部类名.this.a”的方式来调用(this就近)

注意:

因为this是在对象内部指代自身的引用,所以this只能调用实例变量、实例方法和构造方法,不能调用类变量和类方法,也不能调用局部变量。

6.3.1封装概述

Java中封装的实质就是将类的状态信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法开实现对隐藏信息的操作和访问。

封装反映了事物的相对独立性,有效避免了外部错误对此对象的影响,并且能对对象使用者由于大意产生的错误操作起到预防作用。同样面向对象编程提倡对象之间实现松耦合关系。

封装的好处在于隐藏类的实现细节,让使用者只能通过程序员规定的方法来访问数据,可以方便的加入存取控制修饰符,来限制不合理的操作。

注意:

松耦合就是指尽量减少对象之间的关联性,以降低他们之间的复杂性和依赖性。

6.3.2封装的步骤

1.修改属性的可见性

将Person类中的属性public修改为private即可

public class  Person{
  
          private String name;
          private String gender;
          private String age;          
}

分析:将public修改为private后,其他类就无法访问,如果访问则需要进行封装的第二部

2.设置setter和getter()方法

将Person类中的私有属性添加setter和getter()方法

public class Person{
  private String name;
  private String gender;  
  private int  age;  
  public String getName(){    
    return name;
  }  
  public void setName(String name){    
    this.name=name;
  }  
  
  public String getGender(){   
    return gender;
  }  
  pubic void setGender(String gender){    
    this.gender=gender;
  }  
  public int getAge(){    
    return age;
  }  
  public void setAge(int age){    
    this.age=age;
  }  
}

3.设置属性的存取限制

此时,还没对属性设置合法性检查,需要在setter方法中进一步利用条件判断语句进行赋值限制。

示例20:

为setter方法设置限制

public class Person {


    public String name;

    public int age;

    public String gender;


    public String getName(){
        return name;
    }

    public void  setName(String name){

        this.name=name;
    }

    public String getGender(){

        return gender;
    }

    public void setGender(String gender){

        this.gender=gender;
    }

    public int getAge(){

        return age;
    }

    //修改set方法,设置合法性检查
    public void  setAge(int age){

        if (age<0||age>150) {
            System.out.println("***输入年龄为"+age+",该年龄不合法,将重置***!");
            return;
        }
        this.age=age;
    }



    //构造方法
    public Person(){

        this.name="无名氏";
        this.gender="男";
        this.age=18;
    }

    public Person(String name,String gender,int age){

        this.name=name;
        this.gender=gender;
        this.age=age;
    }

    //方法:自我介绍方法:转义字符:\r表是把光标移到所在行开头;\n是把光标移到下一行开头

    public void say(){

        System.out.println("自我介绍以下\r\n姓名:"+this.name+"\r\n性别:"+this.gender+"\r\n年龄:"+this.age+"岁");
    }


}

5.4.1包的概述

Java中的包机制也是封装的一种形式。

包的主要有以下方面的作用:

1).包允许将类组合成较小的单元(类似文件夹),易于找到和使用相应的类文件

2).防止命名冲突:Java中只有在不同包中的类才能重名。不同的程序员命名同名的类在所难免,类名就容易管理了,A定义了一个类Sort,封装在包A中,B定义了一个类Sort,封装在包B中,在使用时,为了区别A和B定义的Sort类,可以通过包名区分开,如A.Sort和B.Sort分别对应于A和B定义的Sort类。

5.4.2包的定义

定义包的语法格式如下:

package包名:

package是关键字

包的声明必须是Java源文件中的第一条非注释性语句,而且一个源文件只能有一个包声明语句,设计的

包需要与文件系统结构相对应。因此,在命名包时,要遵守以下编码规范。

1).一个唯一的包名前缀通常是全部小写的ASCII字母,并且是一个顶级域名com、edu、gov、net及org,通常使用组织的网络名的逆序。例如,如果域名为javagroup.net,可以声明包为“package net.javagroup.mypackage;”

2) 包名的后续部分依次不同机构各自内部的规范不同而不同。这类名规范可能以特定目录名的组成来区分部门、项目、机器或注册名、如“package net.javagroup.research.powerproject”。research表示项目名,

powerproject表示部门名

 

6.4.3包的使用

示例21:

使用包将Person类和PersonTest类进行分类

import cn.shujia.pack1.Person;

使用访问修饰符

6.5.1类和类成员的访问控制

包实际上是一种访问控制机制,通过包来限制和制约类之间的访问关系。访问修饰符也同样可以限制和制约类之间的访问关系。

1.Java中类的访问修饰符

作用域\修饰符同一包中非同一包中
public可以使用可以使用
默认修饰符(default)可以使用不可以使用

2.类成员的访问修饰符

public:公有的

被声明为public的类、方法、构造方法和接口能够被任何其他类访问。

如果几个相互访问的public类分布在不用的包中,则需要导入相应public类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。Java程序的main() 方法必须设置成公有的,否则,Java解释器将不能运行该类

调用一个包中所有的类可以用   .*

 

protected:受保护的

被声明为protected的变量、方法和构造方法能被同一个包中的任何其他类访问,也能够被不同包中的子类访问。

protected访问修饰符不能修饰类和接口,方法和成员变量能够声明为protected,但是接口的成员变量和成员方法不能声明为protected

子类能访问protected修饰符声明的方法和变量,这样就能保护不相关的类使用这些方法和变量。

下面的父类使用了protected访问修饰符,子类重载了父类的bark()方法。

 1 public class Dog{
 2     protected void bark() {
 3         System.out.println("汪汪,不要过来");
 4     }
 5 }
 6 class Teddy extends Dog{  // 泰迪
 7     void bark() {
 8         System.out.println("汪汪,我好怕,不要跟着我");
 9     }
10 }

如果把bark()方法声明为private,那么除了Dog之外的类将不能访问该方法。如果把bark()声明为public,那么所有的类都能够访问该方法。如果我们只想让该方法对其所在类的子类可见,则将该方法声明为protected。

private:私有的

私有访问修饰符是最严格的访问级别,所以被声明为private的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为private

声明为私有访问类型的变量只能通过类中公共的Getter/Setter方法被外部类访问。

private访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据

 public class Dog{
 2     private String name;
 3     private int age;
 4     public String getName() {
 5         return name;
 6     }
 7     public void setName(String name) {
 8         this.name = name;
 9     }
10     public int getAge() {
11         return age;
12     }
13     public void setAge(int age) {
14         this.age = age;
15     }
16 }

子中,Dog类中的name、age变量为私有变量,所以其他类不能直接得到和设置该变量的值。为了使其他类能够操作该变量,定义了两对public方法,getName()/setName() 和 getAge()/setAge(),它们用来获取和设置私有变量的值。

默认的:不使用任何关键字

不使用任何修饰符声明的属性和方法,对同一个包内的类是可见的。接口里的变量都隐式声明为public static final,而接口里的方法默认情况下访问权限为public。

如下例所示,类、变量和方法的定义没有使用任何修饰符

1 class Dog{
 2     String name;
 3     int age;
 4   
 5     void bark(){  // 汪汪叫
 6         System.out.println("汪汪,不要过来");
 7     }
 8     void hungry(){  // 饥饿
 9         System.out.println("主人,我饿了");
10     }
11 }

如何使用访问控制符

访问控制符可以让我们很方便的控制代码的权限:

  • 当需要让自己编写的类被所有的其他类访问时,就可以将类的访问控制符声明为 public。

  • 当需要让自己的类只能被自己的包中的类访问时,就可以省略访问控制符。

  • 当需要控制一个类中的成员数据时,可以将这个类中的成员数据访问控制符设置为 public、protected,或者省略。

  • 作用域\修饰符同一类中同一包中子孙类中其他包
    private可以使用不可以使用不可以使用不可以使用
    默认修饰符可以使用可以使用不可以使用不可以使用
    protected可以使用可以使用不可以使用不可以使用
    public可以使用可以使用可以使用可以使用

示例23:

Person和 Test类在同一包中

public class Person{
  
  	private String name;

    public int age;

    protected String gender;
}


Test类中:

public void test1(){

        Person person = new Person();
        person.gender="111";
        person.name="111";//非法,报错
    }

6.5.2 static关键字

一个类可以创建n个对象。如果n个对象中的某些数据需要共用,就需要使用static关键字修饰这些数据。

Java中,一般情况下调用类的成员都需要先创建类的对象,然后同过对象进行调用。使用static关键字可以实现通过类名加"."直接调用类的成员,不需要创建类的对象。使用staic修饰的属性和方法属于类,不属于具体的某个对象。

1.用static关键字修饰属性

将Person类的name、gender和age属性保留,新建一个static修饰的属性,并调用。

分析如下:

使用static修饰的属性不依赖于任何对象,用类名直接加"."调用即可。

使用static修饰的属性不依赖于任何对象,用类名直接加“.”调用即可。

示例24:

public Person class{
  
  public static int PERSON_LIVE;//人的生命只有一次
}

测试:

public void test1(){

      Person.PERSON_LIVE=1;

    }

在实际开发中,用static关键字修饰属性的最常用场景就是定义使用final关键字修饰的常量。使用final

关键字修饰的常量在整个程序运行时都不能被改变,和具体的对象没有关系,因此使用static修饰,例如“

static final int PERSON_LIVE”

注意:

1.常量名一般由大写字母组成

2.声明常量时一定要赋值初值

2.用static关键字修饰方法

用staic修饰的方法称为静态方法或者类方法,不用static关键字修饰的方法称为实例方法

实例25:

将Person中的showDetails()方法使用static关键字修饰,并调用

public class Person{
  
  public static void showDetails(){
    System.out.println("1111111111");
  }
}


测试:
public static void main(String[] args) {
        Person.showDetails();
    }

注意:

静态方法只能访问静态成员,实例方法可以访问静态和实例成员。之所以不允许静态方法访问实例成员变量,是因为实例成员变量是属于某个对象的,而静态方法在执行时,并不一定存在对象。同样,因为实例方法可以访问实例成员变量,如果允许静态方法调用实例方法,将间接地允许它使用实例成员变量,所以它也不能调用实例方法。基于同样的道理,静态方法中也不能使用关键字this。

main()方法是一个典型的静态方法,它同样遵循一般静态方法的规则,所以它可以由系统在创建对象之前就调用

本章总结:

1.了解了类和对象,也学习了如何定义类,创建对象和使用对象

2.面向对象的优点:与人类的思维习惯一致,封装使信息隐藏,提高了程序的可维护性和安全性,一个类可以创建多个对象的实例,体现了重用性。

3.对象用来描述客观事物的一个实体,由一组属性和方法构成

4.类是具有相同的顺序和方法的一组对象的集合

5.使用类的步骤是,使用class定义类、使用new关键字创建类的对象,使用"."访问类的属性和方法。

6.如果一个类中包含了两个或两个以上方法,他们方法名相同,方法参数列表不同,则称为给重载。

7.构造方法用于创建类的对象。构造方法的作用主要就是创建对象时执行一些初始化操作。可以通过构造方法重载来实现多种初始化行为。

8.封装的好处在于隐藏类的实现细节,让使用者只能通过程序员规定的方法来访问数据库,可以方便的加入存取控制修饰符,以限制不合理操作。

9.Java中包含类的访问修饰符和类成员访问修饰符,其作用与不同。

10.static关键字修饰的属性和方法,不属于具体的对象,采用类名加"."方法即可直接访问。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值