变量:1.成员变量(field)类里面定义
1.1实例变量(没有static,属于实例)
1.2类变量(有static,属于类本身)
2.局部变量
2.1方法里的局部变量。仅在方法内有效
2.2代码块的局部变量,仅在代码块内有效
2.3形参。整个方法内有效
重写(Override)和重载(overload)
重写是指对父类方法进行重写。
重载是指一个类里面多个方法名一样,但是参数不一的方法。
super和this都不能出现在static方法里面。
super可以用来调用父类构造方法,必须出现在子类构造方法的第一行
this可以调用同一个类的构造方法
多态:java引用变量有两个类型,一个是编译时类型,一个是运行的类型,编译时的类型由声明该变量时使用的类型决定,
运行是的类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现所谓的多态。
态:行为 多态:同一个类型的变量,在执行同一个方法时表现多种行为特征。
父类到子类的关系(向上转型):从一般到特殊的关系
Animal a=new Wolf();
结论:1.子类的实例,完全可以当成父类对象使用
父类的引用变量,指向子类
子类抛弃父类没有的方法,如果子类对父类方法进行了重写则用子类方法。
向上转型:把子类对象付给父类引用变量是,称为向上转型。
这种类型转换时应先通过instanceof运算来判断是否可以成功转换。
使用继承的注意点:
1.尽量隐藏父类内部数据 属性尽量用private
2.不要让子类可以随意访问、修改父类的方法。不提供给给其它类的方法用private,只提供给子类的用protected。不让子类重写用final
3.不要在父类构造方法中调用被子类重写的方法。
啥时候需要用到父类派生出来的新的子类:
1.子类需要额外添加属性,而不仅仅是属性值的改变
2.子类需要增加自己的独有的行为方式(包括新增方法,重写方法)
初始化块:
初始化快的修饰符只能用“static”,也就是静态初始化块。
eg:
public class Person {
{
int a = 6;
if (a > 4) {
System.out.println("Person初始化块:局部变量a的值大于4");
}
System.out.println("Pserson de 初始化块");
}
{
System.out.println("这是第二个初始化块");
}
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
new Person();
}
}
运行结果:
Person初始化块:局部变量a的值大于4
Pserson de 初始化块
这是第二个初始化块
构造方法
初始化块某种程度上是构造方法的一个补充,初始化块在构造器之前执行。
初始化块不能接收任何参数,可以把构造方法中提取相同代码,更好的提高初始化代码复用性。
包装类:
java8种基本数据类型不支持面向对象机制,java提供了包装类的概念:
byte--->Byte char--->Character
short--->Short float--->Float
int--->Integer double--->Double
long--->Long boolean--->Boolean
eg:
// 包装类对象
int i=5;
Integer iObj=new Integer(i);
// 获取包装类中的基本类型
int i=iObj.intValue();
JDK1.5后提供了自动装箱和自动拆箱。
eg:
public static void main(String[] args) {
// 直接把一个基本类型变量赋给Integer
Integer inObj = 5;
// 直接吧一个boolean类型变量赋给一个Object类型变量
Object boolObj = true;
// 直接吧一个Interger对象赋给int类型变量
int it = inObj;
// 用instanceof来判断是否可以类型转换
if (boolObj instanceof Boolean) {
// 把Object对象强制类型转为Boolean类型,在赋给boolean变量
boolean b = (Boolean) boolObj;
System.out.println(b);
}
}
输出结果为:true
基本类型和String之间的转换:
通过String.valueOF()转换
-------------------------------------->
基本类型 String对象
<--------------------------------------
通过parseXxx()方法或者利用包装类的构造器
eg:
public static void main(String[] args) {
String intStr="123";
// 把一个String转成int变量
int it1=Integer.parseInt(intStr);
int it2=new Integer(intStr);
System.out.println(it1);
System.out.println(it2);
// 把一个float变量转成String变量
String ftStr=String.valueOf(2.34f);
System.out.println(ftStr);
}
==和equals方法
==:如果两个变量是基本类型变量且都是数值类型(不一定要求数据类型严格相同),则只要两个变量值相等就返回true;
如果是两个引用类型变量,则必须只想同一个对象时。
equals:判断两个字符串相等,只要两个字符串所包含的字符序列相同,则返回true;
eg:
public static void main(String[] args) {
int it = 65;
float fl = 65.0f;
System.out.println(it == fl);
char ch = 'A';
// 输出true
System.out.println(it == ch);
String s1 = new String("hao");
// 输出true
String s2 = new String("hao");
// 输出false
System.out.println(s1 == s2);
// 输出true
System.out.println(s1.equals(s2));
}
重写equals方法应该满足一下条件:
1.自反性:对任意x,x.equals(x)都返回为true;
2.对称性:对任意x,y。如果y.equals(x)为true,则x.equals(y)定为true;
3.传递性:对任意x,y,z,如果x.equals(y),y.equals(z)为true则x.equals(z)定为ture;
4.一致性:只要x,y信息不变,调用多少次都是返回同样结果,要嘛都为true,要嘛都为false;
5.对任意:对任何不是null的x,x.equalss(null)一定返回false.
final修饰符
1.fianl关键字可以用于修饰类、变量和方法。
2.final修饰变量(成员和局部),一旦获得初始值将不能被重新赋值;
3.final成员变量必须由程序员显示初始化,希望不会对final成员隐示初始化。
4.final修饰形参不能被赋值
public void test(final int a){
a=5;//这句是不合法的
}
5.final修饰局部变量在定义时没有指定默认值,则可以在后面代码中对final变量赋初始值,但不能重复。
final double d;
6.d=2.3;//允许
7.d=3.0;//不合法
8.final修饰的方法不可被重写
9.final类不可以有子类
abstract 抽象:
1.抽象类和方法必须用关键词 abstract 修饰;
2.抽象类不能被实例化(new);
3.抽象方法必须在抽象类中,抽象类中可以无抽象方法。
4.抽象类只能被继承;
5.抽象方法在子类中必须被重写;
interface 接口:
1.接口定义基本语法:
[修饰符] interface 接口名 extends 父接口1,父接口2.。。
{
零个到多个常量定义。。。
另个到多个抽象方法定义。。。
}
2.修饰符:public或者省略,如果省略则默认此阿勇包权限访问控制符,既只能在相同包下才能访问接口。
3.一个接口可以继承多个父类接口,但不能继承类。
4.接口里不能包含构造器和初始化块定义。
5.接口的成员变量只能是常量,接口里的方法只能是抽象方法,默认加上了abstract.
6.接口不能用于创建实例,实现用个 implements 关键字
[修饰符] class 类名 extends 父类 implements 接口1,接口2.。。
{
类体部分
}
1)implements 必须放在extends之后
2)这个类必须全部实现接口的所有抽象方法
7.接口和抽象类对比
相同点:
1)都不能被实例化
2)都可以包含抽象方法,实现接口或者继承抽象类必须实现抽象方法。
不同点:
1)接口只能包含抽象方法,抽象类可以包含普通方法
2)接口不能定义静态方法(static),抽象类可以定义静态方法
3)接口只能定义静态常量成员变量,抽象既可以普通成员常量,也可以静态成员常量
4)接口不包含构造函数和初始化块,抽象类可以包含构造函数和初始化块
5)一个类只能继承一个抽象类(extends),却可以实现多个接口(implements)
内部类:放在另一个类内部的类就叫内部类,放在方法里面的叫局部内部类
1.非静态内部类
eg:
public class Cow {
private double weight;
public Cow() {
}
public Cow(double weight) {
this.weight = weight;
}
// 定义一个非静态内部类
private class CowLeg {
private double length;
private String coulor;
private double weight = 123.0;
public CowLeg() {
}
public CowLeg(double length, String color) {
this.length = length;
this.coulor = color;
}
public void setLength(double length) {
this.length = length;
}
public double getLength() {
return this.length;
}
public void setCoulor(String color) {
this.coulor = color;
}
public String getColor() {
return this.coulor;
}
public void info() {
System.out.println(coulor + length);
// 用过外部类名.this.varName访问指定类的成员变量
System.out.println(Cow.this.weight);
System.out.println(weight);
}
}
public void test() {
CowLeg cl = new CowLeg(1.12, "黑白相间");
cl.info();
}
public static void main(String[] args) {
Cow cow = new Cow(234.5);
cow.test();
}
}
运行结果:黑白相间1.12
234.5
123.0
1).非静态内部类可以直接访问其外部类的private成员;
2).可以通过OutterClass.this.propName来访问外部类的Field,通过this.propName访问内部非静态实例成员变量Field.
3).静态成员不能访问非静态成员,所以外部类的静态方法、代码块不能访问非静态内部类。
2.静态内部类:使用static修饰的内部类。
静态内部类只能方位外部类的类成员,不能访问外部类的实例成员。
eg:
public class StaticInnerClassTest {
private int prop1 = 5;
private static int prop2 = 9;
static class StaticInnerClass {
private static int age;
public void accessOuterProp() {
System.out.println(prop2);
}
}
}
enum枚举类:
1与普通类对比:
1.1使用enum定义、非抽象的枚举类默认会使用final修饰,所以枚举类不能派生子类。
1.2枚举类的构造器只能用private访问控制符。
1.3枚举类的所有实例必须在枚举类的第一行显示列出,否则这个枚举类永远不能产生实例,
这些实例默认会自动添加 public static final.
eg:
public enum Gender{
Male,FEMALE;
private String name;
private void setName(String name){
switch(this){
......
}
}
public String getName(){
return this.name;
}
}