目录:
toString()
boolean equals(Object obj)
static
单例类(单个实例)
final
abstract
Object 类的简单特征
因为一切类都是Object类的子类
第一个重要方法:toString(),它负责把返回该对象的“描述性字符串”。
当你“打印输出”一个对象时,实际上就是打印输出该对象的 toString 方法的返回值。
Object 类提供的 toString() 方法,返回值就是 类名@hashCode值
——所以很多时候,都要重写 toString() 方法
第二个重要方法:boolean equals(Object obj)
这个方法用于按【程序自己的规则】判断两个对象是否相等。
== 用于判断两个【基本类型】的变量(表达式/直接量),它们的值是否相等。
A。当比较【基本类型】的值时,程序并不管它的数据类型,只比较实际的值的大小。
B。如果是【引用类型】的变量(不包括包装类,因为包装类可以自动拆箱)
== 要求被比较两个【引用变量】,引用同一个实例才会返回 true
重写equals 方法的标准:
1. 如果当前对象与被比较对象,本省就想同,直接返回 true。
2. 要求当前对象与被比较对象的类型相同,
关键属性值也相同——此时才返回 true
static
A。static 只是一个标志。
有 static 修饰,表明被修饰的成员属于类。
没有 static 修饰,表明它是属于实例的。
B。static 成员(Field、方法、初始化块),与类共存亡
static 成员,建议总是通过类名来访问。
如果见到通过实例的情况,你可以先将实例替换成类名。
C。必须先有类,再有对象。
有可能出现的情况,JVM 已经有类了,依然没有实例。
绝对不可能:JVM 已经有了该类的实例,但该类信息依然不存在!
【规则】:【static 成员】不允许访问【非 static 成员】!(有static的不能访问没有static的,因为类成员(有static的)比实例早出现)
【【静态成员】不能访问【非静态成员】】
this引用,super 都不允许出现 static 方法中。
当程序直接访问一个Field ,实际上前面省略了:
【如果Field 是实例Field,相当于省略了this】
【如果Field 是类Field ,相当于省略了类名】
StaticTest 程序 及 运行结果:
public class StaticTest
{
// 定义了一个类Field,它与StaticTest 类本身共存亡
static int count = 20;
public static void main(String[] args)
{
// 只是定义一个st引用变量
// 但st并未指向任何有效的对象
StaticTest st = null;
// 对于静态Field、static方法,我们建议将实例可以直接替换成类名
System.out.println(st.count); // st 写成 StaticTest
}
}
输出结果为 20
StaticEx 程序 及 运行结果:
public class StaticEx
{
int age;
// 实例初始化块,负责对实例Field 进行初始化
{
age = 20;
abc();// 相当于 StaticEx.abc();非静态可以访问静态的,
//因为abc是static修饰的,属于类,所以前面省略类名
}
static
{
abc();// static静态初始化块调用静态方法
// age = 12;// 错误,age 是非静态的,【静态成员】不能访问
//【非静态成员】,此时位于静态初始化块中
}
public void test()
{
System.out.println("age的值是:" + age);// age 相当于 this.age
}
// 通俗:猪八戒.吃(西瓜),烤(鸡翅) // 烤鸡翅前省略了主语,
// 即猪八戒,可以成this
public static void abc()
{
System.out.println("~~static修饰的abc方法~~" );
}
}
单例类(单个实例)
在某些时候,我们只允许为某个类创建一个实例。
要实现单例:
A。构造器不能暴露。
否则就可以自由的创建很多个实例。
B。暴露一个方法,由该方法来返回实例。
由于程序必须通过该方法来获取实例,
所以在调用该方法之前,肯定没有实例。
因此只能通过类来调用,所以该方法必须使用 static 修饰
C。使用静态 Field 来“缓存”已有的实例。
每次在获取实例之前,先判断是否已经“缓存”过实例。
如果没有缓存过,就创建,否则直接返回“缓存”的实例。
final
- 变量:成员变量(类变量和实例变量)和局部变量(方法里局部变量、代码块的局部变量)
- 方法
- 类
1.final 修饰变量
— 该变量值只能被赋值一次,不可改变!
A - final 修饰成员变量。
Java 成员变量(Field),默认是可以由系统执行初始化,程序员可以不指定初始值。
但是,final 修饰的成员变量(Field),【必须由程序员】执行初始化
原因(反证法):假如让系统执行初始化,变量的值要么是0、0.0、\u0000、false、null。final 又导致这些变量的值不允许被改变,那么这些变量就失去价值了。
A1。如果final修饰实例变量,可以再如下3个地方为final实例变量指定初始值。
1. 定义时指定初始值。
2. 初始化块
3. 构造器
最多只能指定一次初始值
普通方法不允许为 final 实例变量赋值
A2。如果 final 修饰类变量,可以在如在2个地方为final类变量指定初始值。
1. 定义时指定初始值。
2. 类(静态)初始化块。
最多只能指定一次初始值。
普通类方法、普通实例方法、普通初始化块、构造器都不能为 final 类变量赋值。
B - final 修饰局部变量。
Java 的局部变量,默认就【必须由程序员来指定初始值】。
final 修饰的局部变量之后,只有一个变化:
final 局部变量依然【必须由程序员来指定初始值】
但是,一旦指定了初始值之后以后它的值就不能改变了,只能一次赋值!
final 修饰的变量,它会被执行”宏替换“
final 修饰的变量:1. 声明时就指定了初始值,而且 2. 初始值在编译时就可以确定。
~~~~~~~ 那么这个变量就不存在!
”宏替换“ —— 就是”查找、替换“
补充: 对于执行“宏替换”,变量名应该多个单词连缀而成
对于字母全部大写,单词与单词之间以下划线隔开
宏替换 — 例:
public static void main(String[] args)
final String s1 = "今天";
final String s2 = "是";
final String s3 = "周一";
final String s4 = s1 + s2 + s3;
上面程序中定义了几个变量? 0 个 宏替换,直接没有"今天";"是""周一",直接调用打印
定义了几个 String 对象? 1 个 因为 s1 + s2 + s3为 ”今天是周一“,有字符串的长度,放在缓存中,所以为对象。
Ps:JVM 会把所有用过的对象进行缓存,第二次可以用
例1:
String a = "今天是周一";
String b = "今天是" + "周一";
System.out.println(a == b); // a、b必须指向同一个对象才相等
上面程序输出为 true。因为 在编译时候,编译器已经把”+ 运算“ 计算出来。"今天是周一"已经缓存过了,由于” + “ 前后的值都是”直接量“,可以直接计算。
例2:
String a1 = "今天是";
String a2 = "周一";
String a3 = "a1 + a2";
String a4 = "a1 + a2";
上面程序输出为 false。因为 a1,a2 都是变量,他们的值只有在运行时才能确定下来,a3,a4 的值只能在运行时动态地确定。因此无法直接用缓存的字符串
2.final方法
final 修饰的方法不能被重写(Override)!
两同、两小、一大
两同:方法名,形参列表相同
两小:子类重写的方法的返回值类型必须比父类方法的返回值类型更小,或相等
子类重写的方法的声明抛出的异常必须比父类方法声明抛出的异常更小,或相等
一大:子类重写的方法的访问权限必须比父类方法的访问权限更大,或相等
好处:禁止父类方法被重写,避免了父类被破坏
注意点:
A。final 与 private 没有价值!
private 方法它是不能被重写的。
因此再用 final 修饰 private 方法没有太大的实际意义
3.final 类
final 类不能有子类
final 类比较安全
—— 就是为了更加的安全。由于它没有子类,它的方法、Field 就可以更好的被保护。
典型的,Java 中包含String、Math、所有包装类,都是 final 类。
abstract 修饰符
修饰类或方法
抽象类:使用 abstract 修饰的类就是抽象类。
【有得有失】: 得:增加了一个功能,可以包含抽象方法。
失:不能创建实例。
其他的,普通类可以有的,抽象都可以有。
抽象类的三个注意点:
A。【虽然抽象类不能创建实例,但它依然有构造器,
它的构造器主要是供其子类的构造器调用】
B。【抽象类完全可以没有抽象方法】
C。【抽象类总是不能创建实例的,即使它没有包含抽象方法】
抽象方法:A。使用 abstract 修饰
B。没有方法体(有abstract修饰,后面不能加 {~~此为方法体~~})
注意点:
A。【抽象方法不能有方法体,花括号部分{} 】
B。【只要在方法后出现花括号,即使花括号中没有任何代码,也算有方法体】
C。【abstract 不能与final 同时出现:
对于abstract 方法而言,该方法应该由子类重写,final 不允许被重写,因此不能同时出现。
对于abstract 类而言,该类主要用于派生子类,final 类不允许被继承,因此不能同时出现】
abstract 与 final 【永远互斥】!
D。【abstract 与 static 不能同时修饰方法】
E。【abstract 和 private 不能同时修饰方法
原因:private 意味着该方法不能被子类访问
abstract 要求方法必须由子类重写 两者冲突】
抽象类的作用:
主要是与 ”模板模式” 联系在一起的。
需求场景: 程序需要实现A方法,但A方法又需要调用B方法,
B方法在该类中暂时不知道怎么实现(不同的子类对B方法的实现【不同】)
此时就需要把B方法定义成抽象方法。
为抽象类定义子类;
A。子类要么为抽象父类的所有抽象方法提供实现
否则你的子类也只能是抽象类
以上
写在最后:
此刻,我有些明白,她口中的所谓的:我觉得你不是我想要的那种爱情了。不是她变心了,而是我自己一直处于一种病态,总是一味的觉得爱你就要给你最好的,毫无底线,逆来顺受,对方说什么就是什么,对方要什么就满足什么,对方生气了TA忍,对方需要TA的时候就理TA,不需要TA的时候就像空气一样对待。这种情况在于,喜欢多的那一方心态已经失衡,潜意识认为我在乎TA,我不能惹TA生气,如果TA生气,那么我们就有分手的危险。殊不知,越是这么卑微,越是这么低下,对方越来不起你,也就越有恃无恐。真正的爱情是建立在双方平等的基础上的,两情相悦才是爱情长久的保障。现实生活中很多人遇到TA说没感觉了,就以为自己对TA还不够好,接着就是比以前对TA更好更卑微,结果通常让对方更厌烦。这个问题的根本原因在于:你的魅力下降到TA难以感兴趣的地步。
其实,这个问题她是给我说过的,但是我却不以为意,或者说,我是误解了,没有认识到本质。现在,竟然有些豁然开朗。好在我现在认识到也不迟,虽然她昨晚和我真诚的坦言让我很难过,她说,她觉得她对我的爱配不上我对她的爱,她觉得她是个坏女孩,哈哈,这个傻瓜,其实并不是她的问题,是我对她的爱陷入了误区,只是她也不知道这是什么误区,其实她的内心里还是爱我的,至少她对说出了她的内心想法,她告诉我,如果你不想分手我们就继续好着吧,两个小时之前,我还一直在想,有意义吗,现在看来,很有意义,她是个傻不列颠的小可耐那,我怎么忍心让她来承认她是个坏坏的花心姑凉那。但是现在的这些想法,我暂时不打算告诉她,我也早就给她说过,爱情也是需要适当的呵护的,现在,我将尝试用正确的方式来悉心呵护我们的爱情,请你期待吧,当然,不会是很刻意的维护,是建立在彼此都相处的很舒服的基础上。