Java基础4——类和对象

    该网站是我学习的途径之一,欢迎大家使用http://how2j.cn?p=4094。另外,Java基础也学习了毕向东老师的视频,真的有条理,内容多且有一定的深度,特别推荐初学者学习。

1、面向对象及其特性

    面向对象即将客观事物看作具有属性和行为的对象,通过抽象找出同一类对象的共同属性和行为,构成类。类是对一类对象的描述,对象是类的具体实例。类通过变量和方法来定义对象的属性和行为。

    面向对象基于面向过程,将功能封装(隐藏对象的属性和实现细节,仅对外提供公共访问方式,Java里的封装体:方法、类、包、框架)进对象,实现了复杂问题简单化,从执行者变成指挥者,使代码可重用、可靠。

    面向对象的特征:抽象、封装、继承和多态。

2、包

(1)Java编译单元

    一个java源代码文件,称为一个编译单元。由三部分组成:所属包的声明;引入包的声明;类和接口的声明。

(2)包

    包是一组类的集合,一个包可以包含若干个类文件,还可以包含若干个包。作用:对类文件进行分类管理;给类提供多层命名空间,避免类名冲突;提供包一级的封装和存储权限(同一包内的类,默认可互相访问)。

    包的命名必须“独一无二”,使用小写字母。命名方式建议:将机构的Internet域名反序,作为包名的前导;若包中有任何不可用于标识符的字符,用_替代;若包名中的任何后缀与关键字冲突,后缀_;若包名中的任何部分以数字或其它不能用作标识符起始的字符开头,前缀_。

    包的声明:package packageName[.package2]; 省略则属于默认包。包名就是文件夹名,即目录名,但目录名不一定是包名。包的根目录在classpath来确定,Eclipse会自动设置classpath环境变量。

package packa;

public class DemoA extends packb.DemoB{
	public void show(){//不同包之间访问,类和方法都要public
		System.out.println("demoA show run");
		method();
	}
}
package packb;

public class DemoB{
	protected void method(){//protected不同包中类的继承,同一包中方法的覆盖
		System.out.println("demoB method run");
	}
}
package pack;

public class PackageDemo{
	public static void main(String[] args){
		packa.DemoA d=new packa.DemoA();
		d.show();
	}
}

    set classpath=c:\myclass

    javac –d c:\myclass DemoB.java //先编译被使用的类

    javac –d c:\myclass DemoA.java

    javac –d c:\myclass PackageDemo.java //用.表示地址,存放在当前目录

    java pack.PackageDemo//包名.类名访问其它包中的类

(3)引入包

    为了更方便使用其它包中所提供的类,用import语句引入所需类,简化类名的书写。Java编译器为所有程序自动引入包java.lang.*。

    import package1[.package2].(classname|*); package1[.package2]包的层次,对应文件目录;尽量不用*导入一个包中的所有类,仅导入需要的类,不然会占内存。不能直接使用导入包的子包中的类。当不同包中的类同名时,必须加包名。

(4)静态引入

    单一或全体引入指引入类中某一指定的或所有静态成员,引入后可直接使用变量名。如import static java.lang.Math.PI|*;或import static java.lang.System.*;可省略System,直接使用out.println();

(5)jar包

    Java的压缩包,方便项目的携带,方便使用。-c创建新的归档文件;-f指定归档文件名;-t列出归档目录;-v在标准输出中生成详细输出。

    切换到待压缩包或类所在目录,

    jar –cf a.jar pack packa //创建.jar文件;

    jar –tf a.jar //列出jar中的包和类目录,并额外有一个文件夹MEIA-INF存配置清单文件;右键WinRAR也可以看;jar –tf a.jar > c:\1.txt显示目录重定向为文件;

    set classpath=c:\myclass\a.jar java pack.PackageDemo //执行.class文件。

    从网上下载.zip工具,解压后有.jar导入到classpath,通过API学习使用。

JDK中的压缩包:

    jdk\src.zip,Java所有类的源代码;

    jdk\jre\lib\rt.jar,Java类库;

    jdk\lib\Tools.jar,编译工具所用类,JDK全是编译工具,编译工具用类写的,类要用虚拟机运行,所以JDK需要jre运行环境。

3、类声明和对象创建

(1)类声明

[public] [abstract|final] class 类名称
[extends 父类名称]
[implements 接口名称列表]
{
	数据成员声明及初始化;//又称字段(field)、域、域变量、属性,用变量表示
	方法声明及方法体;//用函数表示
}

    一个编译单元中只能有一个public类,该类名与.java文件名相同,编译单元中的其它类往往是public类的辅助类,经过编译,每个类产生一个.class文件。如果一个类是独立的,需要对外提供服务,就不要与另一个public类放在同一文件中。

(2)构造方法

    构造方法用来描述初始化(属性或行为)算法,编译器不可能自动完成。用new生成一个对象时,会自动调用该类的构造方法为新对象初始化,不能在程序中显式地调用。

    通常被声明为共有的(public);必须和类同名;没有void等返回值类型;不要过多写打印等其它功能。构造方法可以重载,使用this()简化代码,必须放在第一句,一般用参数个数少的构造方法调用参数多的,便于阅读和维护。

    一个类如果没有定义构造方法,会隐含一个方法体为空的无参构造方法,称为默认构造方法,默认构造方法的权限与类权限一致。如果提供了一个构造方法,不论是否含参数,默认构造方法就没有了。使用默认构造方法时,如果类声明中没有给实例变量赋初值,则对象属性值为0或null。

(3)数据成员

    存放整个类中所有对象共有的属性,可以是任意数据类型。成员变量作用于整个类,因对象而存在于堆内存中,数据成员都有默认值。

[public|protected|private]
[static] [final] [transient] [volatile]
数据类型 变量名1[=变量初值],变量名2[=变量初值],…;

    实例变量,没有static修饰的变量,存储所有实例都需要的属性,不同实例的属性值可能不同。初始化分为声明时初始化、构造方法中初始化和初始化块{}。访问实例变量的值<实例名>.<实例变量名>。

    静态变量,也称为类变量,用static修饰,在整个类中只有一个值。适用于类中所有对象都相同的属性值;经常需要共享的数据;系统中用到的一些常量值final static修饰。初始化分为声明时初始化和静态初始化块static{}。访问静态变量的值<类名|实例名>.<类变量名>,最好使用类名。(static对对象的共享数据进行单独空间存储,节省空间;随着类的加载而加载,消失而消失,声明周期长)

public class Hero {
	/*通过该方法可以看出,属性初始化时,按照静态初始化块、属性声明、初始化块、构造方法的先后顺序执行*/
	public String name=getName("属性声明");
	
	public Hero(){
		name=getName("构造方法");
	}
	
	{
		name=getName("初始化块");
		//给所有对象进行统一初始化,对象一建立就运行,在构造方法之前运行。
	}
	static{
		getName("静态初始化块");
		//给类进行初始化,随着类的加载(执行new创建对象或使用类方法等)而执行,只执行一次,且优先于主函数。Hero h=null;此时类不会加载
        }
	
	public static String getName(String name){
		System.out.println(name);
		return name;
	}
	
	public static void main(String[] args) {
		new Hero();
	}
}

(4)方法成员

    方法是为了完成一个操作而组合在一起的语句组,使代码变得简化和可重用。在方法中定义的变量称为局部变量,该变量没有赋默认值,必须在使用前声明和赋值。其作用域从声明处开始,至包含该变量的块结束。

[public|protected|private]
[static] [final] [abstract] [native] [synchronize]
返回类型 方法名([参数列表]) [throws exceptionList]
{
	方法体;
}

    实例方法,不加static,实例对象的功能或行为,只有建立一个对象才能访问。如果方法里访问了对象属性,该方法就必须设计为实例方法。

    静态方法,用static修饰,类的共同功能或行为,不依赖于类的某个具体实例,即没有访问非静态数据。不能被声明为抽象的,无需创建类的实例就可以调用。

    类外调用<对象名|类名>.<方法名>([参数列表]),类体内部方法与方法之间可以直接互相调用。静态方法不能调用实例方法或访问实例变量,不能用this或super,因为this代表对象;可以调用静态方法或访问静态变量,如main方法、Math类中的方法都是静态的。

    方法重载指方法名一样,但参数类型或个数不同。在调用方法的时候,会根据传递的参数列表,自动调用对应的方法。重载时,用参数个数较少的方法调用较多的。

    可变长参数列表,把类型相同但数量可变的参数传递给方法,作为数组对待。声明(类型名…参数名)。

(5)对象创建

    对象引用声明:类名 引用变量名,默认为空引用,并没有生成对象。

    对象创建:引用变量名=new类名();new在内存中为该类型的对象分配内存空间,返回该对象的引用。

    匿名对象:当对象的方法只调用一次,调用结束该对象成为垃圾;或将匿名对象作为实际参数进行传递,方法执行结束该对象成为垃圾。这样写比较简化。

    对象初始化过程:Hero h=new Hero();new时JVM加载器会将Hero.class的静态变量、方法等信息加载至方法区;执行静态代码块,对类进行初始化;开辟堆内存空间,分配内存地址;建立对象属性,先默认初始化、属性初始化,再初始化块初始化,构造函数初始化;最后将内存地址赋给栈内存中的h变量。

    对象调用成员过程:h.setName("huo");先开辟一块栈空间存储name局部变量和this引用(存对象的地址),(此处还没弄懂)…静态方法调用时不会用到堆,直接操作方法区。

(6)主函数

    public static void main(String[] args)

    主函数格式是固定的,其中的main不是关键字,但是可以被JVM识别,仅有字符串数组可以改变,args可以是任意标识符。

    JVM在调用主函数时,传入new String[0]。在调用java命令执行.class文件时,java MainDemo yao cong zhu,将类后面跟的字符串自动保存至字符串数组中。

4、类的访问权限控制

(1)可见性修饰符

    指定如何访问类和类成员(方法、数据域)。private和protected只能用于类成员,默认修饰和public可以用于类或类成员。在局部变量上使用可见性修饰符会导致编译错误。

    可见性递增:private(同一类)->默认(同一包)->protected(同一包&子类)->public

    使用技巧:属性通常用private修饰起来;方法一般用public方便调用;会被子类继承方法用protected;作用范围最小原则。

    子类可以重写父类的protected方法,并将其可见性改为public,却不能削弱父类方法的可访问性。

(2)get()、set()方法

    为了防止数据被篡改且使类更易于维护,应将数据成员设为private。使用get方法返回数据成员的值,set方法设置数据成员的值。

    public returnType getPropertyName(){}

    public void setPropertyName(dataType propertyValue){}

    如果一个类的所有数据成员都是私有的、没有set方法且没有一个set方法的返回值是指向数据成员的引用,则该类是不可变的。String类不可变。

(3)final

    final修饰的类不能被继承,修饰的方法不能被重写,修饰的数据是常数。编译时可以作优化。

    final实例变量可以在类定义时给出初始值,最晚在构造方法结束之前给出初始值。static final表示类变量必须在声明的同时进行初始化,不初始化则为默认值。

(4)this

    如果一个局部变量和一个类变量具有相同的名字,则局部变量优先,同名类变量被隐藏。此时用this关键字代表对象本身的引用名使用实例变量this.<变量名>(哪个对象在调用this所在函数,this就代表哪个对象)。隐藏的静态变量可以通过<类名>.<静态变量>进行引用。

public Boolean compare(Person p){
         returnthis.age==p.age;
}

    this()还用于构造方法的调用。

5、单例模式

    设计模式是指解决某一类问题最行之有效的方法,来自于开发中的经验总结。Java中有23种设计模式。其中,单例设计模式又叫做 Singleton模式,指的是一个类在内存中只存在一个对象。

    实现单例模式有三步:构造方法私有化,外部不能使用new实例化;静态属性指向new对象;静态方法返回该静态属性,外部调用者通过该方法获取定义的对象,每一次都是获取同一个对象。一个事物需要单例时,它的属性和方法不变,在该类中加入这三步。

    饿汉式单例模式类一加载就创建对象,无论是否用到该对象。如果在构造方法里写了性能消耗较大,占时较久的代码,比如建立与数据库的连接,那么就会在启动的时候感觉稍微有些卡顿。开发一般用饿汉式,简单安全。既不低效,也不存在安全隐患。

public class Single {
    private Single(){//私有化构造方法
    }
 
    //在类中创建一个本类对象。 因为是类属性,所以只有一个
    private static Single instance = new Single();//为什么要私有化?
     
    //提供一个方法可以获取该对象
    public static Single getInstance(){
        return instance;
    }
}

    懒汉式单例模式,方法被调用时才创建对象,也叫对象的延时加载。存在安全隐患,CPU在某一时刻只能处理一个程序,几个程序同时执行时,CPU瞬间进行切换。如多个人同时调用,A调用完if后,CPU突然去执行另外一个程序了,B进来,一判断也为null,又切换Anew对象,再执行B时又new一对象。如果上锁,A进去后,B不能进去,但是加锁程序效率变低。用双重判断来解决。

public static synchronized Single getInstance(){
    if(s==null){
        Synchronized(Single.class){ //最多读两次锁
            if(s==null){
	        s=new Single()
            }
	}
    }
}
public class Single {
    private Single (){       
    }
  
    //准备一个类属性,用于指向一个实例化对象,暂时指向null
    private static Single instance=null;
      
    //public static 方法,返回实例对象
    public static Single getInstance(){
        //第一次访问的时候,发现instance没有指向任何对象,这时实例化一个对象
        if(null==instance){
            instance = new Single ();
        }
        //返回 instance指向的对象
        return instance;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值