1. Java标识符(identifier)
Java语言中,为各种变量、方法和类等起的名字称为标识符
Java标识符的命名规则:
应以字母、下划线、美元符开头(不能以数字开头)
后跟字母、下划线、美元符或数字
Java标识符大小写敏感,长度无限制
注意事项:
类名命名:类名首个字母必须大写,多个单词组成的,每个单词首字母都要大写。
方法名命名:方法名一般首个字母小写(构造方法例外,构造方法一般与类名同名),多个单词组成方法名,第一个单词全部小写,后面单词首字母大写 eg . getSum
。
变量名命名:变量命名规则同方法名名。
注意:不能使用java中的关键字做标识符。
2. Java关键词(key words)
Java语言有51个关键字,其中const和goto虽然被保留但未使用。你不能使用保留关键字来命名类、方法或变量。
保留关键字
数据类型:
Boolean int long short byte float
double char class interface
流程控制:
if else do while for switch case
default break continue return try catch finally
修饰符:
public protected private final void
static strictfp abstract transient
synchronized volatile native
动作:
package import throw throws
extends implements this Super instanceof new
保留字:
true false null goto const
3. 数组作为方法参数和返回值
数组作为方法参数传递,传递的参数是数组内存的地址。
数组作为方法的返回值,返回的是数组的内存地址
4.单变量int作为方法参数
仅传值,将变量的值(实参argument)复制给形参(parameter),不改变原实参的值。
5.对象数组初始化
java中基本数据类型数组与自定义对象数组的区别是,在创建后,基本数据类型数组可以直接对数组元素赋值、引用等操作;而自定义对象数组,需要对数组中的每个对象元素独立进行创建,然后才可以对其赋值、引用等操作,如果没有单独对每个对象元素创建,会导致空指针异常。
对象数组必须给每个元素实例化
Employee myEmp[]=new Employee[3];
int i;
for(i=0;i<myEmp.length;i++)//为对象数组中每一个元素实例化
myEmp[i]=new Employee();
基本数据类型数组在创建后可直接赋值,引用
int[] priArr = new int[3];
priArr[0] = 1;
proArr[1] = 2;
6.构造方法重载(Overload)
当类中有有参的构造方法时,系统就不会在默认给无参的构造方法了,所以当类中写了有参的构造方法后,要用无参的构造方法时必须写出来。
7. CopyArray的使用
部分参考:参考
源码:public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
参数:
src:要复制的数组(源数组)
srcPos:复制源数组的起始位置
dest:目标数组
destPos:目标数组的下标位置
length:要复制的长度(一定要注意最后这个参数是长度不是下标!!!)
String[] arr = {"A","B","C","D","E","F"};
System.arraycopy(arr ,3,arr,2,2);
从下标为3的位置开始复制,复制的长度为2(复制D、E),从下标为2的位置开始替换为D、E
复制后的数组为:
String[] arr = {"A","B","D","E","E","F"};
ArrayList的remove()和add(int ?,object ?)都是是根据此方法进行的操作。
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = new int[3];
int[] b = new int[10];
a[0] = 5;
a[1] = 4;
a[2] = 3;
System.arraycopy(a,0,b,1,3);//从数组a的0号index开始,复制值到数组b,从数组b的1号index开始填充,依次填充,长度为3
for(int i = 0;i<b.length;i++) {
System.out.println("b[" +i+" ]" +" = "+b[i]);
}
}
具体使用System.arraycopy(a,0,b,1,3);//从数组a的0号index开始,复制值到数组b,从数组b的1号index开始填充,依次填充,长度为3
结果:
b[0 ] = 0
b[1 ] = 5
b[2 ] = 4
b[3 ] = 3
b[4 ] = 0
b[5 ] = 0
b[6 ] = 0
b[7 ] = 0
b[8 ] = 0
b[9 ] = 0
问题1:
4超出了a数组的长度,编译错误!!!
System.arraycopy(a,0,b,1,4);
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: arraycopy: last source index 4 out of bounds for int[3]
问题2:
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = new int[5];
int[] b = new int[3];
a[0] = 5;
a[1] = 4;
a[2] = 3;
a[3] = 3;
a[4] = 10;
System.arraycopy(a,0,b,1,4);//从数组a的0号index开始,复制值到数组b,从数组b的1号index开始填充,依次填充,长度为4
for(int i = 0;i<b.length;i++) {
System.out.println("b[" +i+" ]" +" = "+b[i]);
}
}
编译错误:
xception in thread "main" java.lang.ArrayIndexOutOfBoundsException: arraycopy: last destination index 5 out of bounds for int[3]
8. Java继承
对于public类型和protected的方法、属性、类,都可以被继承
对于default类型的方法、属性、类不可以被包外的类继承,
(类是default但方法是public,这样的方法也不能被包外的类继承,因为这个类是default所以这个类都不能被继承,更不用说方法了)
(类是public但属性是default,这种类的包外子类对这个default的属性不可见(所有规则符合public, protected, default,private四种类别)
9.抽象类
抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。
如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。
10. Java对多态的理解
public class Employee {
private String name;
private double salary;
public Employee(String name, double salary)
{
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public double getSalary(){
return salary;
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
public void Hello() {
System.out.println("Hello! Employee");
}
}
Manager继承Employee
public class Manager extends Employee{
private double bonus;
//Employee没有默认构造器
public Manager(String name, double salary) {
super(name, salary);//必须要写这一行!!!一定要使用super来构建父类,鉴于父类写了有参构造器但没写无参构造器,所以这里必须要调用super
//this.name = name;
//this.salary = salary;
bonus = 0;
}
public double getSalary(){
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
public void setBonus(double b) {
bonus = b;
}
public void Hello() {
System.out.println("Hello! Manager");
//super.Hello();
}
public void Hello(String str) {
System.out.println("Hello!"+str);
}
}
public class ManagerTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Manager boss = new Manager("Carl Cracker", 80000);
boss.setBonus(5000);
Employee [] staff = new Employee[3];
// fill the staff array with Manager and Employee objects
staff[0] = boss;
staff[1] = new Employee("Harry Hacker", 50000);
staff[2] = new Employee("Tommy Tester", 40000);
// print out information about all Employee objects
for (Employee e : staff)
System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());
boss.Hello();
staff[0].Hello();
//staff[0].Hello("aa");不能调用重载方法
boss.Hello("aa");
}
}
output
name=Carl Cracker,salary=85000.0
name=Harry Hacker,salary=50000.0
name=Tommy Tester,salary=40000.0
Hello! Manager
Hello! Employee
Hello!aa
方式
多态体现为父类引用变量可以指向子类对象。
多态的定义与使用格式
定义格式:父类类型 变量名=new 子类类型();
前提条件:必须有子父类关系。
注意:在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。
Creature a = new Rabbit();
向上转型
Creature中的原有属性:A
Creature中的原有方法:a
Rabbit中的特有属性:B
Rabbit中的特有方法(包括对Creature原有方法的重载和其他方法名不同的方法):b1
Rabbit中对Creature中原有方法的重写(方法名和返回值类型,参数列表均相同的方法):b2
当调用a的方法和属性时,若涉及到A,a(且a未被重写),则正常按照Creature中的方法和操作进行调用,若涉及到B,b1,则编译出错,该属性或方法向上转型后不可见,涉及到b2,则调用子类的b2
public class Wine {
public void fun1(){
System.out.println("Wine 的Fun1...");
fun2();
}
public void fun2(){
System.out.println("Wine 的Fun2...");
}
}
public class JNC extends Wine{
/**
* @desc 子类重载父类方法
* 父类中不存在该方法,向上转型后,父类是不能引用该方法的
*/
public void fun1(String a){
System.out.println("JNC 的 Fun1...");
fun2();
}
/**
* 子类重写父类方法
* 指向子类的父类引用调用fun2时,必定是调用该方法
*/
public void fun2(){
System.out.println("JNC 的Fun2...");
}
}
public class Test {
public static void main(String[] args) {
Wine a = new JNC();
a.fun1();
}
}
-------------------------------------------------
Output:
Wine 的Fun1...
JNC 的Fun2...
从程序的运行结果中我们发现,a.fun1()首先是运行父类Wine中的fun1().然后再运行子类JNC中的fun2()。
分析:在这个程序中子类JNC重载了父类Wine的方法fun1(),重写fun2(),而且重载后的fun1(String a)与 fun1()不是同一个方法,由于父类中没有该方法,向上转型后会丢失该方法,所以执行JNC的Wine类型引用是不能引用fun1(String a)方法。而子类JNC重写了fun2() ,那么指向JNC的Wine引用会调用JNC中fun2()方法。
所以对于多态我们可以总结如下:
指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载父类的方法也不可以。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。
参考:Java对多态的理解
11.java中equals和等号(==)的区别浅谈
java中的数据类型,可分为两类:
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号,比较的是他们的值。
2.复合数据类型(类)
当他们用双等号进行比较的时候,比较的是他们在内存中的存放地址,
所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。
JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法。
这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了。
如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,
他们之间的比较还是基于他们在内存中的存放位置的地址值的,
因为Object的equals方法也是用双等号进行比较的,所以比较后的结果跟双等号的结果相同。
代码参考:参考
Boolean bool1 = new Boolean(false);
Boolean bool2 = new Boolean(false);
if(bool1 == bool2)
{
if(bool1.equals(bool2))
{
System.out.println("a");
}
}
else
System.out.println("b");
Output:b
12.java中super的用法
super只在子类中出现
super有三种用法
【1】 super.xxx;
xxx可以是类的属性。
例如super.name;即从子类中获取父类name属性的值(当子类重写了父类的变量时)
【2】 super.xxx();
xxx()可以是类中的方法名。
super.xxx();的意义是直接访问父类中的xxx()方法并调用
【3】 super();
此方法意义是直接调用父类的构造函数。
super(无参/有参)即调用父类中的某个构造方法,括号里的内容根据你所调用的某个构造函数的变化而改变
参考1:super的用法
参考2:super的用法示例
13.子类继承父类构造器相关问题
参考:代码实例参考
(一)父类中同时包含无参构造器和有参构造器时
1.当子类的构造器中没有实现super()方法时,默认在调用子类构造方法之前先调用父类的无参构造方法。
2.也可以在子类构造器中使用super(参数列表)来调用父类的有参构造方法,此时super必须写在构造器的第一行。
(只有在使用构造器时super才必须放在第一行,其他时候不一定)
二)父类中只有有参构造器时
1.当父类中只有有参构造器时,默认在子类中必须需要使用super(父类构造器参数)
才能调用父类的有参构造器,可以实现继承。
14.Java类及其属性和方法可以由一个以上的修饰符来修饰
修饰符分为:访问修饰符(public,private,protected)和非访问修饰符(static,final,abstract)等
15.基本数据类型的计算
int i = 8,j = 9;
boolean test = i++>7&&j-->i++;
System.out.println(test);
output:false
int i = 8,j = 9;
boolean test = i>7&&j-->i++;
System.out.println(test);
output:true
16.Java 接口中的defaul,静态方法
参考代码
总结:
1.interface中的default方法default关键词不可省略
2.default方法会被实现该接口的子类继承
3.如果一个类A实现了两个接口b,c且b,c中有同样的default方法(两个default方法参数列表和方法名都相同)则A必须重写这个方法
4.如果子类继承父类,父类中有b方法,该子类同时实现的接口中也有b方法(被default修饰),那么子类会继承父类的b方法而不是继承接口中的b方法
通过接口名称直接调用静态方法,不能用实现类的对象调用静态方法。
package cn.itcast.day10.demo01;
/*
注意事项:不能通过接口实现类的对象来调用接口当中的静态方法。
正确用法:通过接口名称,直接调用其中的静态方法。
格式:
接口名称.静态方法名(参数);
*/
public class Demo03Interface {
public static void main(String[] args) {
// 创建了实现类对象
MyInterfaceStaticImpl impl = new MyInterfaceStaticImpl();
// 错误写法!
// impl.methodStatic();
// 直接通过接口名称调用静态方法
MyInterfaceStatic.methodStatic();
}
}