类和对象

来源:互联网 发布:尔雅网络课程密码 编辑:程序博客网 时间:2024/05/17 22:16

引用

引用的概念,如果一个变量的是类类型,而非基本类型,那么该变量又叫做引用


1.引用和指向

new Hero();

代表创建了一个Hero对象
但是也仅仅是创建了一个对象,没有办法访问它
为了访问这个对象,会使用引用代表这个对象
Hero h = new Hero();

h这个变量是Hero类型,又叫做引用
=的意思指的h这个引用代表右侧创建的对象
代表” 在面向对象里,又叫做“指向


2.多个引用,一个对象

引用有多个,但是对象只有一个。
所有引用都指向了同一个对象。
对象就像 "房产", 引用就像"房产证"
房产证的复印件可以有多张,但是真正的"房产" 只有这么一处


3.一个引用,多个对象

一个引用,同一时间,只能指向一个对象





继承

在LOL中,武器是物品的一种,也是有名称和价格的 
所以在设计类的时候,可以让武器继承物品,从而继承名称和价格属性

extends





方法重载

方法的重载指的是方法名一样,但是参数类型不一样


1.在调用方法的时候,会根据传递的参数类型以及数量,自动调用对应的方法


2.可变数量的参数

可以采用可变数量的参数
只需要设计一个方法
public void attack(Hero ...heros)
即可代表上述所有的方法了
在方法里,使用操作数组的方式处理参数heros即可





构造方法

通过一个类创建一个对象,这个过程叫做实例化 

实例化是通过调用构造方法(又叫做构造器)实现的


1.什么是构造方法

方法名和类名一样(包括大小写)
没有返回类型
实例化一个对象的时候,必然调用构造方法


2.隐式的构造方法

Hero类的构造方法是

public Hero(){
}

这个无参的构造方法,如果不写,就会默认提供一个


    //这个无参的构造方法,如果不写,
    //就会默认提供一个无参的构造方法
    //  public Hero(){ 
    //      System.out.println("调用Hero的构造方法");
    //  }

3.如果提供了一个有参的构造方法

一旦提供了一个有参的构造方法 
同时又没有显式的提供一个无参的构造方法 
那么默认的无参的构造方法,就“木有了“


    //有参的构造方法
    //默认的无参的构造方法就失效了
    publicHero(String heroname){ 
        name = heroname;
    }

4.构造方法的重载

和普通方法一样,构造方法也可以重载






this
this这个关键字,相当于普通话里的“ 

小明说 “我吃了” 这个时候,“” 代表小明 
小红说 “我吃了” 这个时候,“” 代表小红 
""代表当前人物 

this这个关键字,相当于普通话里的“ 
this即代表当前对象

1.this代表当前对象

2.通过this访问属性
通过this关键字访问对象的属性
    //参数名和属性名一样
    //在方法体中,只能访问到参数name
    publicvoidsetName1(String name){
        name = name;
    }
     
    //为了避免setName1中的问题,参数名不得不使用其他变量名
    publicvoidsetName2(String heroName){
        name = heroName;
    }
     
    //通过this访问属性
    publicvoidsetName3(String name){
        //name代表的是参数name
        //this.name代表的是属性name
        this.name = name;
    }

3.通过this调用其他的构造方法
如果要在一个构造方法中,调用另一个构造方法,可以使用this()
    //带一个参数的构造方法
    publicHero(String name){
        System.out.println("一个参数的构造方法");
        this.name = name;
    }
      
    //带两个参数的构造方法
    publicHero(String name,floathp){
        this(name);
        System.out.println("两个参数的构造方法");
        this.hp = hp;
    }





传参
变量有两种类型 基本类型 和类类型 

参数也是变量,所以传参分为 
基本类型传参 
类类型传参

1.基本类型传参
基本类型传参 
在方法内,无法修改方法外的基本类型参数

2.引用与=
如果一个变量是基本类型
比如 int hp = 50;
我们就直接管hp叫变量
=表示赋值的意思
如果一个变量是类类型
比如 Hero h = new Hero();
我们就管h叫做引用
=不再是赋值的意思
=表示指向的意思
比如 Hero h = new Hero();
这句话的意思是
引用h,指向一个Hero对象

3.类类型传参
类类型又叫引用 
不同的引用
指向同一个对象




包: package 

1.把比较接近的类,规划在同一个包下
Hero,ADHero 规划在一个包,叫做charactor(角色)
Item,Weapon规划在另一个包下,叫做 property(道具)
在最开始的地方声明该类所处于的包名

2.使用其他包下的类,必须import
使用同一个包下的其他类,直接使用即可 
但是要使用其他包下的类,必须import





访问修饰符
成员变量有四种修饰符 
private 私有的 
package/friendly/default 不写 
protected 受保护的 
public 公共的 

比如public 表示公共的 
public String name;

而maxHP 没有修饰符即代表package/friendly/default 
float maxHP


1.类之间的关系
类和类之间的关系有如下几种:
以Hero为例
自身:指的是Hero自己
同包子类:ADHero这个类是Hero的子类,并且和Hero处于同一个包下
不同包子类:Support这个类是Hero的子类,但是在另一个包下
同包类: GiantDragon 这个类和Hero是同一个包,但是彼此没有继承关系
其他类:Item这个类,在不同包,也没有继承关系的类

2.private 私有的
使用private修饰属性 
自身:是可以访问的 
同包子类:不能继承 
不同包子类:不能继承 
同包类:不能访问 
其他包类:不能访问



3.package/friendly/default 不写 
没有修饰符即代表package/friendly/default 
    // 无修饰符的属性 hp
    // 自己可以访问
 
    // 同包子类可以继承
    // 不同包子类不能继承
 
    // 同包类可以访问
    // 不同包类不能访问



4.protected 受保护的
    // protected饰符的属性 hp
    // 自己可以访问
 
    // 同包子类可以继承
    // 不同包子类可以继承
 
    // 同包类可以访问
    // 不同包类不能访问



5.public 公共的
任何地方,都可以访问
    // public的属性 name
    // 自己可以访问
 
    // 同包子类可以继承
    // 不同包子类可以继承
 
    // 同包类可以访问
    // 不同包类可以访问




6.总结



那么什么情况该用什么修饰符呢?
从作用域来看,public能够适用所有的情况。 但是大家在工作的时候,又不会真正全部都适用public,那么到底什么情况改用什么修饰符呢?

1. 属性通常使用private封装起来
2. 方法一般使用public用于被调用
3. 会被子类继承的方法,通常使用protected
4. package用的不多,一般新手会用package,因为还不知道有修饰符这个东西

再就是作用范围最小原则
简单说,能用private就用private,不行就放大一级,用package,再不行就用protected,最后用public。 这样就能把数据尽量的封装起来,没有必要露出来的,就不用露出来





类属性
当一个属性被static修饰的时候,就叫做类属性,又叫做静态属性 
当一个属性被声明成类属性,那么所有的对象,都共享一个值 
与对象属性对比: 
不同对象的 对象属性 的值都可能不一样。 
 比如盖伦的hp 和 提莫的hp 是不一样的。 
但是所有对象的类属性的值,都是一样的

1.类属性

类属性: 又叫做静态属性 
对象属性: 又叫实例属性,非静态属性 
如果一个属性声明成类属性,那么所有的对象,都共享这么一个值 
给英雄设置一个类属性叫做“版权" (copyright), 无论有多少个具体的英雄,所有的英雄的版权都属于 Riot Games公司。


2.访问类属性

访问类属性有两种方式
1. 对象.类属性

teemo.copyright

2. 类.类属性
Hero.copyright


这两种方式都可以访问类属性,访问即修改和获取,但是建议使用第二种 类.类属性 的方式进行,这样更符合语义上的理解


3.什么时候使用对象属性,什么时候用类属性

如果一个属性,每个英雄都不一样,比如name,这样的属性就应该设计为对象属性,因为它是跟着对象走的,每个对象的name都是不同的

如果一个属性,所有的英雄都共享,都是一样的,那么就应该设计为类属性。比如血量上限,所有的英雄的血量上限都是 9999,不会因为英雄不同,而取不同的值。 这样的属性,就适合设计为类属性






类方法

1.类方法: 又叫做静态方法 

对象方法: 又叫实例方法,非静态方法 

访问一个对象方法,必须建立在有一个对象的前提的基础上 
访问类方法,不需要对象的存在,直接就访问


2.调用类方法

访问类属性一样,调用类方法也有两种方式
1. 对象.类方法

garen.battleWin();;

2. 类.类方法
Hero.battleWin();;


这两种方式都可以调用类方法,访但是建议使用第二种 类.类方法 的方式进行,这样更符合语义上的理解。
并且在很多时候,并没有实例,比如 随机数的获取办法 
Math.random()

random()就是一个类方法,直接通过类Math进行调用,并没有一个Math的实例存在。


3.什么时候设计对象方法,什么时候设计类方法

如果在某一个方法里,调用了对象属性,比如

public String getName(){
return name;
}

name属性是对象属性,只有存在一个具体对象的时候,name才有意义。 如果方法里访问了对象属性,那么这个方法,就必须设计为对象方法

如果一个方法,没有调用任何对象属性,那么就可以考虑设计为类方法,比如
public static void printGameDuration(){
System.out.println("已经玩了10分50秒");
}

printGameDuration 打印当前玩了多长时间了,不和某一个具体的英雄关联起来,所有的英雄都是一样的。 这样的方法,更带有功能性色彩
就像取随机数一样,random()是一个功能用途的方法
Math.random()





属性初始化

1.对象属性初始化

对象属性初始化有3种
1. 声明该属性的时候初始化 
2. 构造方法中初始化
3. 初始化块


2.类属性初始化

类属性初始化有2种
    1. 声明该属性的时候初始化
    2. 静态初始化块






单例模式

LOL里有一个怪叫大龙GiantDragon,只有一只,所以该类,只能被实例化一次


1.单例模式

单例模式有叫做 Singleton模式,指的的一个类,在一个JVM里,只有一个实例存在。


2.饿汉式

通过私有化其构造方法,使得外部无法通过new 得到新的实例

提供了一个public static的getInstance方法,外部调用者通过该方法定义的对象,而且每一次都是获取同一个对象。 从而达到单例的目的

这种单例模式又叫做饿汉式单例模式,无论如何都会创建一个实例


3.懒汉式

懒汉式单例模式与饿汉式单例模式不同,只有在调用getInstance的时候,才会创建实例


4.什么时候使用饿汉式,什么时候使用懒汉式

饿汉式是立即加载的方式,无论是否会用到这个对象,都会加载。
如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。

懒汉式,是延迟加载的方式,只有使用的时候才会加载。 并且有线程安全的考量
使用懒汉式,在启动的时候,会感觉到比饿汉式略快,因为并没有做对象的实例化。 但是在第一次调用的时候,会进行实例化操作,感觉上就略慢。

看业务需求,如果业务上允许有比较充分的启动和初始化时间,就使用饿汉式,否则就使用懒汉式


5.单例模式三元素

这个是面试的时候经常会考的点,面试题常常会问的问方法是:

什么是单例模式?

回答的时候,要答到三元素
1. 构造方法私有化
2. 静态属性指向实例
3. public static的 getInstance方法,返回第二步的静态属性





枚举类型

1.预先定义的常量

枚举enum是一种特殊的类(还是类),使用枚举可以很方便的定义常量
比如设计一个枚举类型 季节,里面有4种常量

public enum Season {
SPRING,SUMMER,AUTUMN,WINTER
}


一个常用的场合就是switch语句中,使用枚举来进行判断

注:因为是常量,所以一般都是全大写


2.使用枚举的好处

假设在使用switch的时候,不是使用枚举,而是使用int,而int的取值范围就不只是1-4,有可能取一个超出1-4之间的值,这样判断结果就是是而非了。(因为只有4个季节)

但是使用枚举,就能把范围死死的限定在这四个当中

SPRING,SUMMER,AUTUMN,WINTER

而不会出现奇怪的 第5季


3.遍历枚举

借助增强型for循环,可以很方便的遍历一个枚举都有哪些常量

publicclass HelloWorld {
    publicstatic void main(String[] args) {
        for(Season s : Season.values()) {
            System.out.println(s);
        }
    }
}


以上来源:类和对象

原创粉丝点击