1 类中变量:
成员变量:在类中定义,说明对象将要有什么,java会给成员变量一个初始值
局部变量:在类的方法中定义,在方法中临时保存的数据,java不会给局部变量一个初始值
2 构造方法:
有参构造方法:给类中属性赋值
无参构造方法:默认实例化调用
有参构造方法与无参构造方法是可以共存的,但是不会同时触发,根据创建对象时候的传的参数取决于调用哪个
3 静态变量:static修饰的变量为静态变量或类属性,所有对象共享此变量,如果该类有多个对象,其中一个对象将其改变,那么其它对象读此值也是改变后的值
class HelloWorld{
static String name = "张三";
public static void main(String[] args){
System.out.print(HelloWorld.name); //张三
HelloWorld h1 = new HelloWorld();
HelloWorld h2 = new HelloWorld();
System.out.println(h1.name); //张三
System.out.println(h2.name); //张三
h1.name = "隔壁老王";
System.out.println(HelloWorld.name); //隔壁老王
System.out.println(h1.name); //隔壁老王
System.out.println(h2.name); //隔壁老王
}
}
4 静态方法:static修饰的方法为静态方法或类方法,
4.1 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员
4.2 静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法
4.3 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量
5 普通初始化块、静态初始化块:
5.1 普通初始化块:在类中被"{}"包含的变量块为普通初始化块,无法定义方法
5.1 静态初始化块:在类中被"static{}"包含的变量块为普通初始化块,无法定义方法,只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,
不能初始化普通的成员变量。
5.2 程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法
public class HelloWorld {
int num1;
int num2;
static int num3;
public HelloWorld(){
num1 = 91;
System.out.println("通过构造方法给变量num1赋值");
}
{
int num2 = 74;
System.out.println("通过构造方法给变量num2赋值");
}
static{
int num3 = 83;
System.out.println("通过构造方法给变量num3赋值");
}
public static void main(String[] args){
HelloWorld h1 = new HelloWorld();
System.out.println("num1:"+h1.num1);
System.out.println("num1:"+h1.num2);
System.out.println("num1:"+num3);
}
}
#通过构造方法给变量num3赋值
#通过构造方法给变量num2赋值
#通过构造方法给变量num1赋值
#num1:91
#num1:0
#num1:0
6 封装:在类外部不允许直接操作类内部属性
7 继承:子类继承父类,只能单继承
7.1 重写(覆盖):子类重写父类方法,方法名称、返回值、参数位置、参数类型、参数个数都要一样
7.2 创建对象时候,父类属性初始化->父类构造方法->子类属性初始化->子类构造方法
7.3 Object:所有类的祖宗,Object2个重要的属性:
7.3.1 toString :java中直接输出对象,会输出对象在内存的地址,如果想在输出对象的时候显示自己想要看到的,就要在该对象的类中实例化toString方法
public class HelloWorld {
private int cc = 99;
@Override
public String toString() {
return "HelloWorld [cc=" + cc + "]";
}
public static void main(String[] args){
HelloWorld in = new HelloWorld();
System.out.println(in);
}
}
7.3.2 equals():判断两个对象内存地址是否相同,但是现实中经常比较两个对象属性是否相等,并不是比较对象内存地址,这样一来它满足不了,我们就要重写它:
默认比较:给出答案是"不同1"、"不同2" #【注】 ==在比较基本数据类型时候是比较值是否相等,但是在比较引用数据类型的时候实际比较的也是内存地址
public class HelloWorld {
private int cc = 99;
public static void main(String[] args){
HelloWorld hw1 = new HelloWorld();
HelloWorld hw2 = new HelloWorld();
if(hw1.equals(hw2)){
System.out.print("相同1");
}else{
System.out.print("不同1");
}
if(hw1== hw2){ #【注】 ==在比较基本数据类型时候是比较值是否相等,但是在比较引用数据类型的时候实际比较的也是内存地址
System.out.print("相同2");
}else{
System.out.print("不同2");
}
}
}
重写equals(也是有快捷键的与hashcode一起生成,用不到hashcode删除就好了):
给出答案是"相同1"、"不同2"
public class HelloWorld {
private int cc = 99;
public static void main(String[] args){
HelloWorld hw1 = new HelloWorld();
HelloWorld hw2 = new HelloWorld();
if(hw1.equals(hw2)){
System.out.print("相同1");
}else{
System.out.print("不同1");
}
if(hw1.equals(hw2)){
System.out.print("相同2");
}else{
System.out.print("不同2");
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) //两个引用的值是否相同(即两个引用的内存地址是否相同)
return true;
if (obj == null) //判断传入对象是否是空值
return false;
if (getClass() != obj.getClass()) //getClass获取”类对象“中的属性,判断两个对象类型是否相同;, Xx a = new Xx() 生成的是"类的属性",指的是属性的值
return false;
HelloWorld other = (HelloWorld) obj; //判断比较的对象是否是当前类的对象
if (cc != other.cc) //判断属性值是否相同
return false;
return true;
}
}
8 多态:对象的多种多态
8.1 引用多态:
父类的引用可以指向本类的对象
父类的引用可以执行子类的对象
8.2 方法多态:
创建本类对象时,调用的方法为本类的方法
创建子类对象时,调用的方法为子类重写的方法或者父类的方法(当子类没有重写父类的方法就是调用的父类方法,否则就调用子类中的方法)
【注】:如果子类独有的方法,父类通过实例化子类实现多态后,是不允许调用子类自己的方法的:
如:Dog是子类,Animal是父类,Dog有watchDoor方法与run方法,Animal中有run方法
Animal a = new Dog()
a.run() //方法重载,可以
a.watchDoor() //不允许的
8.3 引用类型转换:
8.3.1 向上类型转换(隐式/自动类型转换):小类型大类型(无风险) ,
8.3.1 向下类型转换(强制类型转换):大类型小类型(有风险),装不下,益处,使用instanceif运算符,来解决引用对象的类型,避免类型转换的安全性问题
Dog dog = new Dog()
Animal animal = dog;//向上转换
Dog dog2 = (Dog)animal //向下类型抓奴还
Cat cat = (Cat)animal //【注】编译不报错,运行报错; 编译时认为animal是Cat,当运行时候发现,真正开辟的空间是Dog,没办法将dog转换为cat,所以用instanceof就会解决这个问题
//instanceof
if(animal instanceof Cat){
Cat cat = (Cat)animal
}else{
System.out.println("无法转换");
}
【注】:所以一般在类型转换时候尽量都用instanceof判断
8.4 抽象类:
8.4.1 abstract定义抽象类
8.4.2 abstract定义抽象方法,只有声明不需要实现
8.4.3 包含抽象方法的类是抽象类
8.4.4 抽象类中也可以有普通的方法,也可以没有抽象方法
8.4.5 抽象类不能直接创建,可以定义引用变量
【注】:抽象类不能被直接实例化
//子类继承之后必须要实现抽象方法
public abstract class Test {
public abstract void test();
public abstract void test1();
}
8.5 接口:特殊的类,是一种规范,用interface定义,接口是用来被实现的,修饰符一般建议用public
8.5.1 :接口都是抽象的,在interface前如果未定义abstract(如果不写系统不会报错,运行时候系统会自动给加上,一般不写),一般声明那个接口的名字前面都要加“I”,代表接口
8.5.2 :接口中只能定义常量(public static final修饰)与抽象方法(如果写普通方法系统不会报错,程序运行时候会自动加上,一般不写)
8.5.3 :可以实现多个接口(实现接口可以用implements),类只能单继承,先继承后实现
8.5.4 :实现接口要实现接口中所有方法
【注】:不能使用private、protected,接口不能直接实例化
IPlayGame是游戏接口,PSP与SmartPhone都实现了它,他们都有了玩游戏功能,SmartPhone同时又继承了phone,PSP不属于phone就不需要继承,所以接口使用起来很方便
IPlayGame playgame = new Psp()
IPlayGame playgame1 = new SmartPhone()
8.6 匿名内部类方式使用接口:
//IPlayGame是一个接口,其中有俩个方法test、test1,匿名内部类方式直接实现
public static void main(String[] args){
IPlayGame tt = new IPlayGame(){
@Override
public void test() {
System.out.println('6666')
}
@Override
public void test1() {
// TODO Auto-generated method stub
}
};
tt.test() //6666
}
9 内部类 :内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类
9.1 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
9.2 内部类的方法可以直接访问外部类的所有数据,包括私有的数据
9.3 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
9.4 内部类种类:
成员内部类
静态内部类
方法内部类
匿名内部类
//外部类HelloWorld
public class HelloWorld {
// 内部类Inner,类Inner在类HelloWorld的内部
public class Inner {
// 内部类的方法
public void show() {
System.out.println("welcome to imooc!");
}
}
public static void main(String[] args) {
// 创建外部类对象
HelloWorld hello = new HelloWorld();
// 创建内部类对象
Inner i = hello.new Inner();
// 调用内部类对象的方法
i.show();
}
}
10 静态内部类 :静态内部类是 static 修饰的内部类,,不允许同一个包中的其他类访问该类
10.1: 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
10.2: 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,
则可通过“成员名”直接调用外部类的静态成员
10.3: 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
public class HelloWorld {
private int a = 99;
public static class Inner{
public void show(){
HelloWorld hw = new HelloWorld();
int b = 6;
System.out.println("a:" + hw.a);
System.out.println("b:" + b);
}
}
public static void main(String[] args){
Inner in = new Inner();
in.show();
}
}
11 方法内部类 :方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用
【注意】:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
public class HelloWorld {
private int cc = 99;
public void show(){
final int A = 25;//常量
int b = 1; //方法内部类无法访问方法中的变量
class Inner{
int c = 2;
public void print(){
System.out.print("访问方法内部的常量A:"+A); //25
System.out.print("访问inner类中的属性c:"+c); //2
System.out.print("访问HelloWorld类中的属性cc:"+cc); //99
}
}
Inner in = new Inner();
in.print();
}
public static void main(String[] args){
HelloWorld in = new HelloWorld();
in.show();
}
}
12 final :
修饰类:不允许被继承(最终的方法)
修饰方法:不允许被重写(覆盖)
修饰属性:该类的属性不会进行隐式初始化(类的初始化属性必须有值或者在构造中赋值,只能选择其一)
final public int a;
修饰变量:修饰变量则该变量只能被赋一次值,即变为常量
final int a;