面向对象——成员

Posted houwenbo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象——成员相关的知识,希望对你有一定的参考价值。

技术图片

 

 

是什么

性:对应类中的成员变量

 

Field = 属性 = 成员变量,

语法格式:

修饰符  类型  属性名 =初值 ;

说明:修饰符private:该属性只能由该类的方法访问。

  修饰符public:该属性可以被该类以外的方法访问。    

     类型:任何基本类型,如intboolean或任何类。

举例:

     public class Person{

           private int age;             //声明private变量 age

           public String name = “Lila”;    //声明public变量 name

      }

 

成员变量(或属性)   vs 局部变量

1.相同点:

声明的格式是相同的:数据类型 变量名 = 初始化值

先声明,后使用

变量都有作用域。

2.不同点:

类中声明的位置的不同。

成员变量:在类的一对{}内直接声明的变量

局部变量:方法内声明的,方法的形参位置声明的,构造器内声明的,代码块内声明的都是局部变量。

 ②成员变量可以在数据类型前声明权限修饰符,而局部变量是不可以声明权限修饰符的。

补充:权限修饰符有哪些?public private protected、缺省

 ③成员变量:声明时,有默认初始化值。也就是说,我们在定义成员变量时,可以不显式的赋值。

  整型:byteshort int long 0

浮点型:float double : 0.0

字符型:char0 (或表示为‘u0000‘

布尔型:boolean : false

引用数据类型:null

 

局部变量:没有默认初始化值。必须在调用前,显式的赋值

 

特别的:方法的形参。此局部变量在方法内调用前,不需要赋值。它的赋值,是在方法调用时进行的。

二者在内存中存放的位置,是不同的。

成员变量:存放在堆空间中

局部变量:存放在栈空间中

类变量和实例变量的区别是什么?

类变量也叫静态变量,也就是在变量前加了static 的变量;

实例变量也叫对象变量,即没加static 的变量;

区别在于:

   类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象;

为:对应类中的成员方法

Method =  (成员)方法 = 函数

 技术图片

 

 

一、方法

类中声明的一个结构,能够实现具体功能。

比如:Array.sort(int[] arr)/int Arrays.binarSearch(int[] arr,int value)

二、举例

public void eat(String food){}

public vlid show(){}

public int returnAge(){}

public String info(String nation){}

 

三、方法声明格式

权限修饰符 返回值类型 方法名(形参列表){

方法体

}

四、具体说明

1)权限修饰符:可以理解为被修饰的结构能被调用的范围大小。

有如下权限修饰符:public private protected 缺省

在不确定修饰符是都用public

2)关于返回值类型:

没有返回值:void

有返回值:指明具体的返回值类型,如果方法声明时,有返回值,那么我们就需要在方法执行体中,返回具体的满足相应类型的变量或常量。比如:return 1;return index;

说明:如果方法有返回值,方法体中一定有return关键字

3)方法名,属于标识符。需要命名时,满足表示符的命名规则和规范,见名知意

比如:println()[输出] / sort()[排序] / binarySearch()[二分法查找] / random()[随机数] / sqrt()[开方] / equals()[相等]

4)形参列表:可以声明0个,1个或多个变量。如果声明了多个用隔开

5)方法体:我们调用方法时,要执行的逻辑

方法的功能主要体现在方法体中。

五、方法的额外使用说明

1)方法中可以调用当前类的属性或方法(如果方法A中调用方法A成为递归方法,如果递归方法没有结束功能或表栈内存溢出[StackOverflowError])

2)在方法体中可以使用关键字:returnreturn的意识:返回结果、跳出方法。return后面不能再有执行语句,不会执行。

3)方法内不能定义再方法,但是可以调用方法。

六、类方法(class Method)

1、没有对象的实例时,可以用类名.方法名()的形式访问由static标记的类方法。

2、在static方法内部只能访问类的static属性,不能访问类的非static属性。

3、因为不需要实例就可以访问static方法,因此static方法内部不能有this(也不能有super ? YES!)

4、重载的方法需要同时为static的或者非static的。

七、方法的详细

格式:

    修饰符 返回值类型 方法名(参数类型 形参1,参数类型 形参2….){

  程序代码

  return 返回值;

 

其中:

形参:在方法被调用时用于接收外部传入的数据的变量。

参数类型:就是该形式参数的数据类型。

返回值:方法在执行完毕后返还给调用它的程序的数据。

返回值类型:方法要返回的结果的数据类型。

实参:调用方法时实际传给函数形式参数的数据。

八、方法的调用

方法只有被调用才会被执行

方法调用的过程分析

 

 意:

没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。

 

定义方法时,方法的结果应该返回给调用者,交由调用者处理。

 

方法中只能调用方法,不可以在方法内部定义方法。

九、方法的重载(overload)  loading...

1.定义:在同一类中,相同的方法名,不同的参数列表的方法之间,彼此构成重载!

举例:Arrays中的sort(Xxx[] xxx) / System.out.println(Xxx xxx)

 

总结:"两同两不同". 两同:访问修饰符相方法名相同一。不同:参数个数不同 参数类型不同

 

2.方法的重载与否与方法的形参的变量名没有关系!与方法是否有返回值也没有关系!

 

3.如果确定调用的是一个类的具体的哪个方法?指明方法名--->指明参数的类型

 

 

十、方法的重写(override)

1.定义:子类在继承了父类以后,可以对父类中的同名同参数的方法进行覆盖覆写

 

2.重写以后,如果我们创建子类的对象,通过子类的对象调用子父类中同名同参数的方法,执行的是子类重写父类的方法。

 

3.  概念:子类重写的方法;父类被重写的方法

     方法的声明: 权限修饰符  返回值类型  方法名(形参列表) throws 异常的类型 { }

     

     >子类重写的方法 与 父类被重写的方法的方法名和形参列表都相同

     >子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符

        特别的,子类不能重写父类中声明为private的方法。

     >子类重写的方法的返回值类型 不大于 父类被重写的方法的返回值类型。

        举例:1.父类方法的返回值类型是void,子类要想重写,一定也是void

             2.父类方法的返回值类型是类型A,子类重写父类方法,返回值类型可以是类型A或类型A的子类.不能是类型A的父类

     >*子类重写的方法抛出的异常类型 不大于  父类被重写的方法抛出的异常类型

     

     *****************************

     *规则: 子类与父类中同名同参数的方法必须同时声明为static(不是重写),或者同时声明为非static的(即为重写)。

十一、重写和重载的区别

 技术图片

 

 

 

十二、可变个数形参的方法的使用:jdk5.0新特性

1.可变个数形参的格式:数据类型 ... 变量名

2.可变个数形参的方法在调用时,给可变个数的形参赋值时,可以赋值的个数为:0个,1个,。。。。

3.可变个数形参的方法与同名的方法之间,彼此构成重载

4.可变个数形参的方法与形参类型相同的数组的方法不能同时出现在类中。

5.可变个数形参必须声明为方法形参的最后一个参数。

6.在一个方法的形参位置,最多只能声明一个可变个数形参

 

说明:

1.可变参数:方法参数部分指定类型的参数个数是可变多个

2.声明方式:方法名(参数的类型名...参数名)

3.可变参数方法的使用与方法参数部分使用数组是一致的

4.方法的参数部分有可变形参,需要放在形参声明的最后

 

 

//下面采用数组形参来定义方法

public static void test(int a ,String[] books);

//以可变个数形参来定义方法

public static void test(int a ,String…books);

十三、方法的参数传递

方法,必须有其所在类或对象调用才有意义。若方法含有参数:

形参:方法声明时的参数

实参:方法调用时实际传给形参的参数值

 

Java的实参值如何传入方法呢?

        Java里方法的参数传递方式只有一种:值传递。  即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响。

构造器 (constructor,构造方法)

1.构造器的作用:

创建类的对象 初始化对象的属性

2.语法格式:

修饰符  类名 (参数列表) {

    初始化语句;

}

3. 例:

public class Animal {

private int legs;

public Animal() {legs = 4; }    //构造器

public void setLegs(int i) { legs = i; }

public int getLegs(){return legs;}

}

 

4.说明:

如果在定义一个类时,没有显式的声明类的构造器。那么系统会自动给类提供一个无参的构造器。

如何声明一个类的构造器。格式:权限修饰符  类名(形参列表){  }

如果我们在类中一旦定义类的构造器,那么系统就不再提供默认的无参的构造器了。

类的多个构造器之间,彼此构成重载

总结:类中,一定会有构造器!

5.关于类中属性赋值的先后顺序:

默认初始化

显式初始化

构造器中初始化

通过"对象.属性" "对象.方法"的方法,给属性赋值

6.根据参数不同,构造器可以分为如下两类:

隐式无参构造器(编译器默认提供)

显式定义一个或多个构造器(无参、有参)

 

7.  意:

Java语言中,每个类都至少有一个构造器

默认构造器的修饰符与所属类的修饰符一致

一旦显式定义了构造器,则系统不再提供默认构造器

一个类可以创建多个重载的构造器

父类的构造器不可被子类继承

 

8.调用父类的构造器

子类中所有的构造器默认都会访问父类中空参数的构造器

当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器,且必须放在构造器的第一行

如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错

9.构造器重载

构造器一般用来创建对象的同时初始化对象。如

class Person{

String name;

int age;

public Person(String n , int a){  name=n; age=a;}

}

构造器重载使得对象的创建更加灵活,方便创建各种不同的对象。

构造器重载举例:

public class Person{

   public Person(String name, int age, Date d) {this(name,age);…}

   public Person(String name, int age) {…}

   public Person(String name, Date d) {…}

   public Person(){…}

}

构造器重载,参数列表必须不同

初始化块

是什么

初始化数据的一种方式,是对构造器的补充,

作用

初始化块(代码块)作用:

Java类或对象进行初始化

用在什么地方

类中构造器之前

怎么用

非静态代码块

语法

{

 

      //初始化块的可执行性代码

 

      }

实例

public class InstanceInitTest {

    

    {

        a = 6;

    }

    int a = 9;

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        //输出结果为9

        System.out.println(new InstanceInitTest().a);

    }

 

}

说明

非静态代码块:没有static修饰的代码块

       1.可以有输出语句。

       2.可以对类的属性、类的声明进行初始化操作。

       3.可以调用静态的变量或方法。

       4.若有多个非静态的代码块,那么按照从上到下的顺序依

           次执行。

       5.每次创建对象的时候,都会执行一次。且先于构造器执行

静态代码块

语法

[static]{

 

      //初始化块的可执行性代码

 

      }

实例

class Person {

 public static int total;

 static {

total = 100;

System.out.println("in static block!");

 }

}

说明

静态代码块:用static 修饰的代码块

     1.可以有输出语句。

     2.可以对类的属性、类的声明进行初始化操作。

     3.不可以对非静态的属性初始化。即:不可以调用非静态的属

         性和方法。

    4.若有多个静态的代码块,那么按照从上到下的顺序依次执行。

    5.静态代码块的执行要先于非静态代码块。

    6.静态代码块只执行一次

执行顺序

程序中成员变量赋值的执行顺序:

声明成员变量的默认初始化

↓↓

显式初始化、多个初始化块依次被执行(同级别下按先后顺序执行)

↓↓

构造器再对成员进行初始化操作

↓↓

通过对象.属性对象.方法的方式,可多次给属性赋值

内部类

是什么

 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。

能解决什么问题

1.内部类可以很好的实现隐藏 一般的非内部类,是不允许有 private protected权限的,但内部类可以

2.内部类拥有外围类的所有元素的访问权限

3.可是实现多重继承

4.可以避免修改接口而实现同一个类中两种同名方法的调用。

在什么地方用

一个类的内部

使用注意

1Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。

2Inner class的名字不能与包含它的类名相同;

3Inner class可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访问内部类中的成员需要:内部类.成员或者内部类对象.成员。

分类

成员内部类(static成员内部类和非static成员内部类)

局部内部类(不谈修饰符)、匿名内部类

static内部类(嵌套类)

class Outer {

 

private int id = 1;

public void outerTest() {

Inner1 i1 = this.new Inner1(); // this可以省略

i1.inner1Test();

}

public static class Inner2 { // 嵌套类

 

public static String name = "abc";

 

public static void inner2Test() {

System.out.println("inner2Test");

}

 

private int age;

 

public void innter2Test2() {

System.out.println("inner2Test()...");

}

}

}

 

//调用

public static void main2(String[] args) {

System.out.println(Outer.Inner2.name);

Outer.Inner2.inner2Test();

 

// 创建嵌套类对象

Outer.Inner2 oi2 = new Outer.Inner2();

oi2.innter2Test2();

}

static内部类

class Outer {

 

private int id = 1;

 

public class Inner1 { // 普通内部类, 可以使用任意外部类的成员(包括私有的) 相当于关联了外部类的对象.

 

private int id = 10;

public void outerTest() {

Inner1 i1 = this.new Inner1(); // this可以省略

i1.inner1Test();

}

public void inner1Test() {

System.out.println("id1 : " + Inner1.this.id); // this.id是内部类的当前对象

System.out.println("id2 : " + Outer.this.id); // Outer.this.id是外部类的当前对象

}

}

}

 

//调用

public static void main1(String[] args) {

Outer outer = new Outer();

//outer.outerTest();

//直接创建内部类对象并调用方法

Outer.Inner1 oi1 = outer.new Inner1(); // 必须用外部类对象.new 内部类.

oi1.inner1Test();

}

局部内部类

public static void test1() {

class Inner3 { // 普通局部内部类

private int id;

private String name;

public Inner3() {

}

public Inner3(int id, String name) {

super();

this.id = id;

this.name = name;

}

@Override

public String toString() {

return "Inner3 [id=" + id + ", name=" + name + "]";

}

};

 

Inner3 i3 = new Inner3();

System.out.println(i3);

}

 

//调用

public static void main3(String[] args) {

test1();

}

匿名内部类

1匿名内部类, 因为没有名字, 所以在声明的同时就必须创建对象

2多态引用 = new 父类构造器 或 接口名() {

类体, 类体的部分就是new后面的父类或接口的子类.

};

 

举例:

interface I1 {

void test1();

}

public class InnerClassTest {

public static void main(String[] args) {

I1 i1 = new I1() {

@Override

public void test1() {

System.out.println("我是匿名内部类的test1()...");

}

};

 

i1.test1();

 

new I1() { // 匿名内部类+匿名对象, 在一次性使用中用到

@Override

public void test1() {

System.out.println("我是匿名内部类22222222");

}

}.test1();

}

内部类特性

Inner class作为类的成员:

1可以声明为final

2和外部类不同,Inner class可声明为privateprotected

3Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;

Inner class作为类:

1可以声明为abstract类 ,因此可以被其它的内部类继承

【注意】

static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员。

以上是关于面向对象——成员的主要内容,如果未能解决你的问题,请参考以下文章

python面向对象之类成员

面向对象结构与成员(特殊成员)及相关内置函数

JavaScript面向对象(上)

JavaScript面向对象ES6类的语法静态成员与实例成员

面向对象

python面向对象进阶版