JavaSe ——3、面向对象
来源:互联网 发布:淘宝苹果4s外壳多少钱 编辑:程序博客网 时间:2024/06/06 14:08
this关键字:
- 在构造器中代表正在实例化的对象,在方法中代表正在调用该方法的对象。
- 因为代表的是对象,不可与static一起用,即static(静态成员)不可访问非静态成员。
类内元素:属性、方法、构造函数、初始化块。
方法:
- 方法的传参:都是值传递,不存在引用传递。(形参是基本类型无法改变参数本身的值,引用类型则传入的值是堆地址值,可以改变参数本身的值)
- 方法重载:同一个类,同一个函数名,不同参数(个数or类型)
类的变量(属性)类型:
- 成员变量:类变量(static)和实例变量。
- 局部变量:形参、方法中、代码块中。
- 一个类不能有两个同名的成员变量,一个方法不能有两个同名的局部变量(一个在方法中一个在代码块中也不行)
- 局部变量和成员变量可同名,局部变量会覆盖成员变量,要用成员变量则用this.来引用。
- 静态成员变量在类初始化时会分配内存空间并制定初值,普通成员变量在创建对象时分配内存并制定初值。
- 局部变量在其所在的方法栈内存中,为局部变量赋值时才分配内存。
构造器:
- 如果不写构造器,会自动提供,在创建对象时会初始化,基本类型的属性设为0,引用类型的属性设为null。
public Class People{ private String name; private String age; public People(String name,String age){ this.name = name; this.age = age; } public void main(String[] args){ People p1 = new People("like",25); }}
这么写后就不能通过new People();创建对象。
- 重载构造器:
public People(){}public People(String name){ this.name = name;}
初始化块
普通初始化块:先于构造函数执行,可以把多个构造函数共有的部分放在普通初始化块中,提高代码复用。创建对象时,先执行Object的初始化块,然后父类初始化块,然后自己的。
静态初始化块:类加载时执行,也会先调用Object的静态初始化块,然后父类的,然后自己的。
包装类
toString();重写,可以描述对象信息。
==和equals:
- ==:如果基本类型,数值一样即为true,类型不一样也可以,如果引用类型,则必须引用同一个对象。且不可比较两个没有继承关系的对象,否则编译报错。
- equals方法是Object类的方法,作用和==一样,但是String类重写了equals方法,所以比较字符串的内容是否相等必须用equals方法。
String s1=new String(“abc”);和String s2=”abc”;
String s2=”abc”;执行时,JVM在字符串常量池查看是否纯在”abc”这个常量,存在即之间使s2指向这个常量,不存在则先在常量池创建”abc”,然后s2指向。所以创建了0或1个对象。
String s1=new String(“abc”);同样也是JVM在字符串常量池查看是否纯在”abc”这个常量,如果不存在,则先在常量池创建”abc”,然后在堆内存创建String类的对象,并把常量池的”abc” copy过来(有待考证)。所以创建了1个或2个对象。
常量池中不能有重复的字符串。
单例类:一个类只能创建一个实例。
- 创建步骤
1、需要通过private修饰构造器,从而不能在类外new对象。
2、类内提供生成实例的方法,因为在类外调用,所以需要用public修饰该方法,因为在生成实例前无实例,所以只能通过类来调用,所以修饰该方法同时要用static,且需要在方法中判断该类是否存在实例化对象。
3、通过成员变量缓存已经构建好的实例,该成员变量需要被生成实例的static方法调用,因此也必须为static。
代码:
Class Singleton{ private static Singleton instance; pivate Singleton(){} public static Singleton getInstance(){ if(instance == null){ instance new Singleton(); return instance; } return instance;}public Class Test{ public static void main(String[] args{ { Singleton t1 = Singleton.getInstance(); Singleton t2 = Singleton.getInstance(); System.out.println(t1==t2); //true }}
- 单例模型的应用:
一般在两种场景下会考虑使用单例(Singleton)模式:
1、产生某对象会消耗过多的资源,为避免频繁地创建与销毁对象对资源的浪费。如: 对数据库的操作、访问IO、线程池(threadpool)、网络请求等。
2、某种类型的对象应该有且只有一个。如果制造出多个这样的实例,可能导致:程序行为异常、资源使用过量、结果不一致等问题。如果多人能同时操作一个文件,又不进行版本管理,必然会有的修改被覆盖,所以:
一个系统只能有:一个窗口管理器或文件系统,计时工具或ID(序号)生成器,缓存(cache),处理偏好设置和注册表(registry)的对象,日志对象。
static修饰符
- 静态成员不能访问非静态成员。
final修饰符
修饰类、变量、方法,一旦赋值就不可变。
如果final修饰的成员变量没有在定义时、初始化块中、构造器中赋值,则系统会默认分配0、false或null,final修饰的成员变量必须显式赋值。
final修饰的局部变量可在定义时赋值或在后面赋值,修饰形参不可赋值,在调用时才赋值。
final修饰基本变量,其值不可变,修饰引用变量,因为存的是地址,所以引用对象中的值可变,引用的对象不可变。
final修饰的转变为常量:定义时确定初始值,编译时即可确定值,则为常量,编译时遇到该变量后会被替换为常量。
final修饰的方法不可被重写(比如父类的方法不希望被重写,可用final修饰),但可重载。
final修饰的类不可以有子类。(java.lang.Math)
不可变类(类创建了实例后,实例的属性不可改变)
创建不可变类:
1、用private final修饰属性。
2、提供带参构造器。(new String(“abc”);)
3、不提供setter方法。
4、重写hashcode和equals方法(可选)比如String和包装类就是不可变类。且String重写了hashcode和equals,两个一样的String的hashcode相等。
如果类中private final修饰的是引用类型,在带参构造器时,new一个引用类返回给成员变量,保证不可变性。
缓存
- 缓存不可变类的实例(由于实例不可变,重复创建无意义,加大开销,某个对象需要频繁重复使用,则缓存)
- 写个缓存:
Class Cache{ private static int MAX_SIZE = 10; private static Cache[] cache = new Cache[MAX_SIZE]; private static int pos = 0; private final String name; private Cache(String name){ this.name = name; } private String getName(){ return name; } public static Cache valueof(String name){ for(int i=0;i<MAX_SIZE;i++){ if(cache[i] !=null && cache[i].getName().equals(name)){ return cache[i]; } } if(pos == MAX_SIZE){ cache[0] = new Cache(name); pos = 1; } else{ cache[pos++] = new Cache(name); } return cache[pos-1]; } }
缓存不可变类的应用:
JDK1.5后 Integer类新增了一个参数,为int类型的静态工厂方法valueOf(int i),它的处理流程如下:
if(在实例缓存中存在取值为i的实例)
直接返回这个实例
else{
用new语句创建一个取值为i的Integer实例
把这个实例存放在实例缓存中
}Integer a=new Integer(10); \\创建一个实例Integer c=Integer.valueOf(10);\\创建一个实例,并放在缓存中。Integer d= Integer.valueOf(10);\\直接返回缓存中的实例,所以c==d为true。
内部类:
一个类放在另一个类的内部定义,包含内部类的类叫外部类。
更好的封装:内部类隐藏在外部类中,不允许包内其他类访问。
内部类作为外部类的成员,因此可以访问外部类的私有(private)数据,但外部类无法访问内部类的成员。
仅需要使用一次的类适合用匿名内部类。
内部类作为外部类的成员,分为静态内部类(static修饰)和非静态内部类。
内部类也可以用public、private和protected修饰。
一个含有内部类的类,编译后为两个文件:外部类.class和外部类$内部类.class。
如果外部类的成员变量、内部类的成员变量和内部类的某方法有同名变量,可以用this.变量名和外部类.this.变量名区分。
外部类访问非静态内部类的成员时,需要通过new内部类对象访问,不可直接访问。
非静态内部类不可以有静态的成员。
静态内部类:static修饰的内部类,内部类中可以有静态成员和非静态成员,但只能访问外部内的静态成员。
接口中可以定义静态内部类,用public static修饰。
外部类内部使用内部类,new内部类对象。
外部类以外定义非静态内部类,内部类不可用private修饰,Out.In in = new Out().new In();
外部类以外定义静态内部类:外部类.内部类 in = new 外部类.内部类。
- 内部类的使用技巧:
http://blog.csdn.net/hivon/article/details/606312
垃圾回收(GC)
- 只回收堆内存中的对象,垃圾回收任何对象前会调用finalize()方法,可能让对象复活。
- 对象在内存中的状态:
- 可达:一个以上的引用。
- 可恢复:没有引用,但还未执行finalize()方法。
- 不可达:无任何引用,执行完finalize()方法后也没复活。
- 强制垃圾回收:
- System.gc()
- Runtime.getRuntime().gc()
- 四种对象引用:
- 强引用
- 软引用
- 弱引用
- 虚引用
- JavaSe ——3、面向对象
- JAVAse——面向对象
- JavaSE初学(四)——面向对象3
- JavaSe基础XX05——面向对象
- JavaSe基础XX06——面向对象
- JavaSe基础XX07——面向对象
- JavaSe基础XX08——面向对象
- JavaSe基础XX09——面向对象
- 黑马程序员—javaSE—面向对象
- JavaSE 拾遗(3)——JavaSE 面向对象程序设计语言基础(3)...函数
- JavaSe基础XX10——面向对象——[多态]
- JavaSE初学(二)——面向对象1
- JavaSE初学(三)——面向对象2
- JavaSE初学(五)——面向对象4
- 黑马程序员——javase基础--面向对象
- JavaSE实战——面向对象(练习)
- javase学习之路——面向对象
- JavaSE学习分享——面向对象初识1
- 刷题——Moo University
- POJ 3660 Floyd求传递闭包
- 二叉树的前/中/后 序遍历(递归非递归两种)
- 毕竟是整理看看哇
- 创建型模式--工厂模式
- JavaSe ——3、面向对象
- Mysql学习笔记2
- app应用--->framework层---->hal硬件抽象层---->kernel driver
- 正确的类引用却显示* cannot be resolved
- 乱七八糟学习笔记之jpa标签
- WSGI in Flask --2
- 解决vux 引入组件时Error in render function: "TypeError: _vm.$t is not a function"问题
- 【云栖精选7月刊】抛开晦涩的算法、模型_让我们来谈谈互联网架构
- SSM框架整合