(22)子类对象向父类对象转型之后,所调用的方法一定是被覆写过的方法,这就是对象的向上转型哈~(被覆写过的方法就是在父类中已存在的方法又在子类中被重写之后的方法)如果所调用的方法在子类中没有被重写,则程序会自动去查找父类中的方法。
(23在进行向下转型之前,两个对象必然先发生向上转型关系,这样好建立起关系,否则两个没有关系的对象是不能相互转型的。
(24)Instanceof的使用时机:
(对象名 Instanceof 类名)
判断规则:(父类 Instanceof 子类)失败
(子类 Instanceof 父类)成功
一般情况下都是在转型之前进行一下判断,这样就可以进行比较安全的转型操作。
(25) 如果一个好的类需要覆写Object类中的三个方法:
public String toString():对象输出时的操作 public boolean equals(Object obj):对象比较时的操作
public int hashCode(): 返回该对象的哈希码值。
重写equals()方法时要特别注意:
例:class Student //extends Object
{
private String name;
private int age;
public Student(String name,int age)
{
this.name = name;
this.age = age;
}
public boolean equals(Object obj)
{
if(this==obj)
{
//内存地址的值相等,则肯定是同一个对象
return true;
}
if (!(obj instanceof Student)) //如果不是同一个类
{
return false;
}
Student stu = (Student)obj;
if (stu.name.equals(this.name)&&stu.age==this.age)
{
return true;
}
else
{
return false;
}
}
public String toString()
{
return "姓名:"+this.name+",年龄:"+this.age;
}
}
public class Demo10
{
public static void main(String args[])
{
Student stu1 = new Student("王乾",27);
Student stu2 = new Student("王乾",27);
System.out.println(stu1.equals("51cto"));
}
}
(26)注意点:
在方法中定义的内部类,可以访问外部类的任何属性,但是不能直接访问方法中的参数或变量。
如果想在内部类中访问方法中的参数,则参数前必须加上一个“final”关键字。
例:class Outer
{
private String name = "redking.blog.51cto.com" ;
public void fun(final int i){
final int j = 10 ;
//在方法中定义内部类
class Inner
{
public void print(){
System.out.println("name = "+name);
System.out.println("i+j = "+(i+j));
}
}
new Inner().print();
}
}
public class Demo08
{
public static void main(String args[]){
new Outer().fun(20);
}
}
(27)对象数组的定义格式:
声明对象数组:类名称 [] 对象数组名称 = null ;
为对象数组开辟空间:对象数组名称 = new 类名称[个数] ;
注意:
数组中使用new开辟空间之后,所有的数据都是默认值,对象的默认值就是null。
(28)加入static 声明之后所有的static 类型的属性都保存在了全局数据区之中,所有的对象都共同拥有同一个属性了。
(29)使用static 声明的方法称为类方法,也可以由类名称直接调用。
(30)static方法调用static属性时应当注意在static方法中不能使用this关键字,因为this是表示当前对象,static属性是绝对不能用this表示的,因为static属性不绝对属于某一个对象
例:class Person
{
//为了方便,属性暂时不封装
private String name ;
private int age ;
//所在城市默认为南京
private static String city = "南京" ;
//只编写一个可以修改city的方法
public static void setCity(String c)
{
//this是表示当前对象,static属性是绝对不能用this表示滴~
//因为static属性不绝对属于某一个对象
//this.city = city ; ---->这是错误滴哈~~~
city = c ;
}
(31)Static使用的限制:
1、使用static声明的方法能否访问static声明的属性呢?允许的
2、使用static方法能否访问非static声明的属性呢?不允许的
3、使用非static方法能否访问static声明的属性呢?允许的
4、使用非static能否访问非static声明的属性呢?允许的
(32)如果一个方法想被主方法直接调用,则此方法声明时必须加上public static才可以。
(33)我们在开发中经常把字符串写在前面,然后调用equals方法进行比较哈,这样可以避免出现错误
(34)代码块:java中存在四种代码块:
1、普通代码块:是直接写在各个方法中的代码块
2、构造块:是直接写在类中的代码块,在实例化对象的时候调用,而且每实例化一个对象就要调用一次构造块(多次调用)。构造块优先于构造方法执行。
例:class Demo
{
{
//构造块
System.out.println("Demo类中的构造块~~~");
}
Demo()
{
System.out.println("Demo类中的构造方法~~~");
}
}
public class Demo22
{
public static void main(String args[])
{
new Demo();
new Demo();
new Demo();
new Demo();
new Demo();
}
};
结果:
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
3、静态块:是使用static声明的代码块,静态块只调用一次,而且优先于构造块执行。
作用:为static类型的属性初始化
例:class Demo
{
{
//构造块
System.out.println("Demo类中的构造块~~~");
}
Demo()
{
System.out.println("Demo类中的构造方法~~~");
}
//静态块
static
{
System.out.println("Demo类中的静态块~~~");
}
}
public class Demo23
{
public static void main(String args[])
{
new Demo();
new Demo();
new Demo();
new Demo();
new Demo();
}
};
结果:
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
>>在主类中写的静态块要优先于main方法执行
例:class Demo
{
{
//构造块
System.out.println("Demo类中的构造块~~~");
}
Demo()
{
System.out.println("Demo类中的构造方法~~~");
}
//静态块
static
{
System.out.println("Demo类中的静态块~~~");
}
}
public class Demo24
{
//在主类中写的静态块要优先于main方法执行
static{
System.out.println("##################");
}
public static void main(String args[])
{
new Demo();
new Demo();
new Demo();
new Demo();
new Demo();
}
};
结果:
##################
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
Demo类中的静态块~~~
Demo类中的构造块~~~
Demo类中的构造方法~~~
>>能不能不写主方法而打印出“HELLO WORLD”? 肯定可以,使用静态块哈~
例:public class Demo26
{
//在主类中写的静态块要优先于main方法执行
static{
System.out.println("Hello World!!!");
//为了防止程序继续向后执行,去找main方法,此处可以使系统退出
System.exit(1);
}
};
4、同步代码块
(35)一个类的构造方法如果被私有化了,则外部肯定无法看见,则此时就可以在类的内部产生实例化对象之后将此对象传递到外面去就可以了。
构造方法私有化的目的:在于限制对象的产生
· 如果一个类只能要求有一个实例化对象的时候呢?
· 唯一可以做的就是在产生实例化对象的入口处加入限制 —— 构造方法的私有化
(36)单态设计:
一个类永远只能产生一个实例化对象。 JAVA 类库中有很多地方都使用了单态。
例://一个类只能产生一个实例Single@35ce36,这就叫单态设计
class Single
{
//在类内部产生自己的实例化对象,只实例化一次
private static Single s = new Single();
private Single(){}
public static Single getInstance()
{
//可以在类的内部产生自己的实例化对象
return s;
}
public void print(){
System.out.println("Hello World~~~");
}
}
public class Demo27
{
public static void main(String args[])
{
//如果想调用print方法,则必须产生Single类的实例化对象
Single s1 = null;
s1 = Single.getInstance();
// 对象有引用传递。有没有一种可能可以在Single类的内部产生自己的对象呢?
s1.print();
//要产生第二个对象,也是取滴s对象
Single s2 = Single.getInstance();
System.out.println(s2);
System.out.println(s1);
}
};
结果:
Hello World~~~
Single@35ce36
Single@35ce36