访问的方式
命名规则:名称全大写,下划线分词
public static final double MIN_NUMBER;
static{
MIN_NUMBER=0.1;
}
public class B{
private Random random;
public static void pp(){
System.out.println("pp...");
//静态方法的调用没有要求必须构建B对象,所以很有可能random根本不存在,要求在静态方法中不能访问非静态成员
}
public static void main(String [] args){
B.pp();//调用当前类中的static方法,可以直接方法名.pp()
}
}
public class A{
static {
//类内,所有方法之外
System.out.println("静态代码块");
}
}
public class B{
static {
System.out.println("static...");
}
public static void main(String[] args) {
}
}
需要注意的是
什么时候使用静态
在一个类中反复使用到某个类中的静态方法,如果使用静态导入则在当前类中不需要再写类名称
double a1=-12.345;
System.out.println(Math.abs(a1));
System.out.println(Math.cos(a1));
System.out.println(Math.sin(a1));
在JDK5当中提供了导入静态方法的import语句。
import static java.lang.Math.*;
public class Test1 {
public static void main(String[] args) {
double a1 = -12.345;
System.out.println(abs(a1));
System.out.println(cos(a1));
System.out.println(sin(a1));
}
}
在Integer类定义中查看源代码可以发现一个定义
private static class IntegerCache {
}这实际上就是Integer的cache
Integer num1 = 12;//自动装箱
Integer num2 = 12;//块相等,<=127都是真的
System.out.println(num1 == num2);
是因为在Integer中包含有一个缓存池,缓存值为-128到127之间。
String中包含一个缓存池,当使用某个字符串对象时会首先在缓存池中进行查找,如果存在则直接返回这个对象的地址;如果不存在则会在缓存池中进行创建,创建完成后返回地址
String s1="abc";
String s2="abc";
String s3=new String("abc");//这里会创建2个对象,一个在缓存池中,一个是new导致的新创建对象
System.out.println(s1==s2);//true
System.out.println(s1==s3);//false
String s1="abc";
String s3="ab";
String s2=s3+"c";
System.out.println(s1==s2);//false
如果通过字串拼接所得内容和某个字串内容一致,但是引用不同
认为客观世界由各种对象组成,任何事物都是对象,复杂的对象可以由比较简单的对象以某种方式组合而成
一个类中,使用到了另外一个类
B类方法中使用了A类,此时B类依赖于A类
public class B{
public void pp(){
A a=new A();
a.abc();
}
}
某个类的属性是另外一个类
B类中的属性是A类的引用,此时B类和A类发生了关联关系
public class B{
private A a;
}
某个类继承了另外一个类
B类继承了A类,此时B类和A类的关系是继承关系
继承表示的是is a的语义
public class 汽车 extends 车库{
}//错误的
public class 学生 extends 人{
}//正确的,因为任何一个学生都是人
父类或者接口的引用指向其子类的对象。例如:动物 x=new 猫()
public class Test1 {
public static void main(String[] args) {
动物 x1 = new 动物();
猫 x3=new 猫();//语法正确
// 猫 x4=new 动物(); 语法错误
动物 x2 = new 猫();// 猫extends动物,表示猫具有动物的所有特性,同时猫具备一些自己都有的特性
多态引用时,构造子类对象时的构造方法的调用顺序
父子类之间的一种多态型,例如:动物 x = new 猫()
public class Test1 {
public static void main(String[] args) {
Animal a1=new Cat();
A a=new A();
a.eee(a1);
}
}
class A{
public void eee(Animal animal){
animal.eat();
}
}
class Animal{
public void eat(){
System.out.println("Animal.eat()");
}
}
class Cat extends Animal{
@Override
public void eat() {
System.out.println("就是爱老鼠");
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("就是爱肉骨头");
}
}
在一个类对象上调用相同名称的方法,但是当参数不同时执行不同的动作
public class Test4 {
public static void main(String[] args) {
F4 f=new F4(); f.pp(10);
S4 s=new S4(); s.pp(10);
F4 fs=new S4(); fs.pp(10);
}
}
class F4 {
public void pp(int k) {
System.out.println("F4.pp(int)");
}
}
class S4 extends F4 {
public void pp(int k) {
//子类中定义的同名同参数的方法覆盖了父类中的方法定义,如果需要调用父
类中的方法则需要使用super.pp(k)进行调用
System.out.println("S4.pp(int)");
}
}
public class Test1 {
public static void main(String[] args) {
Fa f2 = new Son();
f2.pp(12);// Son中的pp方法定义覆盖了Fa中的pp方法,new的是Son,所以执行的是Son中的方法
}
}
class Fa {
public void pp(Number kk) {
System.out.println("Fa...");
}
class Son extends Fa {
public void pp(Integer kk) {
System.out.println("Son...");
}
}
子类中方法范围要求大于等于父类中的方法范围,不允许private 返回类型一致,子类方法可以小于等于父类
类型,例如父类Number,子类Integer 参数类型一致
方法的参数一致(个数、类型、顺序),和参数名称无关
返回数据类型一致(因为如果返回类型不一致,则无法进行语法检查,例如父类返回Double,而子类返
回Integer,调用处语法检查是按照Double进行检查还是按Integer检查?允许父类中返回的是父类型,而子类中返回子类型,例如父类中返回的是Number类型,而子类中返回的是Integer)
抛出异常一致,注意实际上允许子类抛出比父类更少的异常
要求子类中的方法范围 >= 父类中方法范围
静态方法覆盖和调用::用谁声明则调用谁的静态方法
@Override//注解可以使IDE工具在编译源代码时进行检查,如果有手写错误则IDE工具报错`
方法的名称相同,参数不同,和返回值类型无关。可以在一个类内或者父子类之间
调用规则:类型最佳匹配原则
class A5 {
public void pp(){
System.out.println("A5.pp()");
}
public int pp(){
}//语法错误,因为在系统中识别一个方法是用【方法名称+参数类型列表】进行,系统会将这两个pp方法识别为同一个方法。注意:在一个类中不允许方法相同
public void pp(int k){
System.out.println("A5.pp(int)");
}
}
class B5 extends A5 {
public void pp(String k){
System.out.println("B5.pp(String)");
}
public void pp(String k,int k1){
}
public void pp(int k,String k1){
}
}
- public double pp(int k){
}
public int pp(int k){
}
// 一个方法有返回值,调用处实际上可以不接收。假设系统可以按照返回类型将这两个方法识别为不同方法,则调用pp(10)就没办法判断到底执行哪个
public void pp(){
}
protected void pp(){
}//语法报错
public class Test1 {
public static void main(String[] args) {
Fa ff = new Son();
ff.pp(10);因为在父类中声明的方法为Integer类型,所以在执行前会自动执行装箱操作,所以调用
的是从父类中继承到的pp(Integer),而不是最佳匹配的pp(int)
}
}
class Fa {
protected void pp() {
System.out.println("Fa.pp()");
}
public void pp(Integer kk){
System.out.println("Fa.pp(Integer)");
}
}
class Son extends Fa {
public int pp(int k) {
System.out.println("Son.pp(int)");
return 10;
}
}