定义合法标识符规则:
- 由26个英文字母大小写,0-9 ,_或 $ 组成
- 数字不可以开头。
- 不可以使用关键字和保留字,但能包含关键字和保留字。
- Java中严格区分大小写,长度无限制。
- 标识符不能包含空格。
Java中的名称命名规范:
- 包名:多单词组成时所有字母都小写:xxxyyyzzz
- 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
- 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
数据类型
类型转换
从键盘获取
import java.util.Scanner;
Scanner scan = new Scanner(system.in);
String name = scan.next();
int age = scan.nextInt();
double weight = scan.nextDouble();
......
获取随机数
double value = Math.random();
switch中的表达式支持的数据类型:
byte,short,int,char,枚举,string
数组的初始化
//一维数组的静态初始化
int[] num = new int[]{1,2,3,4};
//一维数组的动态初始化
int[] num = new int[4];
//二维数组的静态初始化
int[][] num = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
//二维数组的动态初始化
int[][] num new int[3][2];
int[][] num new int[3][];
数组初始化默认值
对象的实例化
person p = new person();
方法中的变量都是局部变量
局部变量在栈中,数组、对象在堆中,字符串、静态变量在方法区中
对象属性的默认初始化值与数组相同
1.在静态方法中可以直接调用所在类的其他静态方法,却不可以直接调用非静态方法,而必须通过实例化之后调用非静态方法;
2.与此相对的,在非静态方法中却可以直接调用所在类的所有静态方法和非静态方法。
匿名对象
new phone().price;
方法的重载,方法名相同,参数的个数或类型不同
可变个数的形参
public void show(String ... strs){}//保存为strs[]
如果变量是基本数据类型,则变量保存的是数据值
如果变量是引用数据类型,则变量保存的是地址值
封装性,高内聚,低耦合
四种权限
一旦显式的定义了类的构造器,系统就不再提供默认的空参构造器
this调用构造器
public person(){
System.out.println("hello");
}
public person(Sring name){
this();
this.name = name;
}
public person(String name,int age){
this(name);
this.age = age;
}
//一个构造器最多只能调用一个其他构造器
import
- 使用的类或接口是java.lang或本包下的,则不用import
- 使用import xxx.*方式可以调用xxx包下的所有结构,但是如果使用的是xxx子包下结构,则仍需要显式地import xxx.子包
类的继承性
class Student extends Person{}
- 一旦子类继承父类后,子类中就获得了父类中的属性、结构。
- 父类中私有的属性和方法,由于封装性的影响,子类不能直接调用。
- 如果没有指定父类,默认父类为java.lang.object
方法的重写
- 子类对父类的方法重新编写
- 方法名和形参列表应该相同
- 子类中的方法权限大于等于父类中的方法权限(子类不能重写父类private的方法)
- 父类中的方法返回值是void,子类中的方法返回值也是void。父类方法的返回值是A类,子类方法的返回值是A类或A类的子类。 父类方法的返回值类型是基本数据类型,子类方法的返回值类型要相同。
super
- super可以调用父类的属性,方法,构造器。
- 调用属性时,通常情况下super可以省略,但如果子父类属性同名,默认为子类属性,调用父类属性需加上super.
- 调用方法时,如果在子类中方法重写了,这是想调用父类中得方法时就需要加上super.
- 调用构造器时,使用方法类似this调用构造器,默认调用super()
- 在构造器中,this()和super()只能二选一
对象的多态性:父类的引用指向子类的对象
//Man exends person
person p = new Man();
p.eat()//多态的使用:当调用父子类同名同参数的方法时,实际调用的是子类重写的方法(父类的虚拟方法)
//p.earnmoney()不能调用子类中独有的方法
总结:
- 编译看左边,运行看右边
- 对象的多态性不适用于属性
- 有了对象的多态性后,内存中实际上是加载了子类特有的属性和方法,但由于变量声明为父类类型,导致只能调用父类中的属性和方法。
如何调用子类特有的属性和方法?
强制类型转换(向下转型)
Man m = (Man)p;
使用强转时可能出现异常
Woman w = (Woman)p;//异常
为了避免异常,使用instanceof
if(p instanceof Woman){
Woman w = (Woman)p;
}
if(p instanceof Man){
Man m = (Man)p;
}
如果B是A的父类,且a instanceof A = true,那么,a instanceof B = true
if(p instanceof Man){//true
Man m = (Man)p;
}
if(p instanceof Person){//true
*******
}
if(p instanceof Object){//true
*******
}
==和equals()的区别
- ==比较变量数值(基本数据类型)或地址(引用数据类型)是否相等
- object中的equals()也是判断地址是否相等
- String\Date\File等都重写了equals(),重写之后比较的是“实体内容”是否相同。
- 比较引用数据类型必须用equals()
toString()
- 输出对象时,实际上就是调用对象的toString(),object默认的toString返回对象的地址
- String\Date\File等都重写了toString(),返回实体内容。
包装类
基本数据类型、包装类、string的转换
//基本数据类型--->包装类
int num = 1;
Integer in1 = new Integer(num);
//Boolean忽略大小写,且只要不是true就返回false
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean("TrUe");
Boolean b3 = new Boolean("true123");
System.out.print(b1);//true
System.out.print(b2);//true
System.out.print(b2);//false
//包装类--->基本数据类型,调用包装类的xxxValue()
int i1 = in1.intValue();
JDK5.0新特性,自动装箱与自动拆箱
int a = 1;
Integer in1 = a; //自动装箱
int b = in1;//自动拆箱
基本数据类型、包装类--->String
//1
int num = 10;
String str = num + "";
//2
int num =10;
String str = String.valueOf(num);
Integer in1 = num;
String str = String.valueOf(in1);
String--->包装类
//1
Integer in2 = new Integer("123");
//2
String str = "123";
int num = Integer.parseInt(str);
static
static可以修饰属性、方法、代码块、内部类
非static修饰的属性为实例变量
static修饰属性(静态变量、类变量),每个对象共用一个静态变量
静态变量的加载早于对象的创建,由于类只加载一次,则静态变量只存在一份,存放在方法区的静态域中。
static修饰方法,类似静态变量。静态方法只能调用静态方法和属性,非静态方法可以随便调。
在静态的方法内,不可以使用this、super
单例的设计模式
一个类只能有一个实例
//饿汉式
class Bank{
private Bank(){//私有化类的构造器
}
private static Bank instance = new Bank();//内部创建类的对象
//提供公共的方法返回类的对象
public static Bank getInstance(){
return instance;
}
}
//懒汉式
class Order{
private Order(){
}
private static Order instance = null;//声明对象、没有初始化
public static Order getInstance(){
if(instance == null){
instance = new Order();
}
return instance;
}
}
代码块
代码块只能使用static修饰
static{
System.out.print("static");
}
{
System.out.print("normal");
}
静态代码块随着类的加载而执行,而且只执行一次。非静态代码块随着对象的创建而执行,每创建一个对象执行一次,且先于构造器执行。
class Root{
static{
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root(){
super();
System.out.println("Root的无参数的构造器");
}
}
class Mid extends Root{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid(){
super();
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg){
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:"
+ msg);
}
}
class Leaf extends Mid{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf(){
//通过super调用父类中有一个字符串参数的构造器
super("尚硅谷");
System.out.println("Leaf的构造器");
}
}
public class LeafTest{
public static void main(String[] args){
new Leaf();
System.out.println();
new Leaf();
}
}
由父及子,静态先行
final
final可以修饰类、方法、变量
final修饰类,该类不能有子类。比如String,System,StringBuffer
final修饰方法,改方法不能被重写。
final修饰变量,该变量为常量。final修饰属性,可以赋值的位置有:显式初始化、代码块中初始化、构造器中初始化。final修饰局部变量,赋值后无法修改。
abstract
abstract修饰的类不可实例化
public abstract void eat();
包含抽象方法的类一定是抽象类。
abstract修饰的方法,只有方法的声明。抽象方法不能被调用,只能在子类中重写或将子类声明为抽象类。
子类重写了父类所有抽象方法后,此子类才可以实例化。
abstract不能修饰private方法、静态方法,final方法。
匿名类
//创建了一匿名子类的对象,p,可以理解为Person的子类
Person p = new Person(){
@Override
public void eat(){
}
@Override void breath(){
}
};
接口
接口使用interface定义
JDK7以前,只能定义全局常量和抽象方法
全局常量:public static final,但是书写时可以省略
抽象方法:public abstract,可省略
interface Flyable{
public static final int MAX = 7900;
int MIN = 1;
public abstract void fly();
void stop();
}
通过类实现接口
class Plane implements Flyable{
//重写抽象方法或将类定义为抽象
}
接口与接口之间可以继承,并且可以多继承。
/*
* 接口的使用
* 1.接口使用上也满足多态性
* 2.接口,实际上就是定义了一种规范
* 3.开发中,体会面向接口编程!
*
*/
public class USBTest {
public static void main(String[] args) {
Computer com = new Computer();
//1.创建了接口的非匿名实现类的非匿名对象
Flash flash = new Flash();
com.transferData(flash);
//2. 创建了接口的非匿名实现类的匿名对象
com.transferData(new Printer());
//3. 创建了接口的匿名实现类的非匿名对象
USB phone = new USB(){
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void stop() {
System.out.println("手机结束工作");
}
};
com.transferData(phone);
//4. 创建了接口的匿名实现类的匿名对象
com.transferData(new USB(){
@Override
public void start() {
System.out.println("mp3开始工作");
}
@Override
public void stop() {
System.out.println("mp3结束工作");
}
});
}
}
class Computer{
public void transferData(USB usb){//USB usb = new Flash();
usb.start();
System.out.println("具体传输数据的细节");
usb.stop();
}
}
interface USB{
//常量:定义了长、宽、最大最小的传输速度等
void start();
void stop();
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盘开启工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println("打印机开启工作");
}
@Override
public void stop() {
System.out.println("打印机结束工作");
}
}
父类 与接口属性重名
interface A {
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A {
public void pX() {
//编译不通过。因为x是不明确的
// System.out.println(x);
System.out.println(super.x);//1
System.out.println(A.x);//0
}
public static void main(String[] args) {
new C().pX();
}
}
JDK8,除了全局常量和抽象方法,还可以定义静态方法、默认方法
public interface CompareA {
//静态方法
public static void method1(){
System.out.println("CompareA:北京");
}
//默认方法
public default void method2(){
System.out.println("CompareA:上海");
}
default void method3(){
System.out.println("CompareA:上海");
}
}
public class SubClassTest {
public static void main(String[] args) {
SubClass s = new SubClass();
// s.method1();
// SubClass.method1();
//知识点1:接口中定义的静态方法,只能通过接口来调用。
CompareA.method1();
//知识点2:通过实现类的对象,可以调用接口中的默认方法。
//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
s.method2();
//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,
//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则
//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//那么在实现类没有重写此方法的情况下,报错。-->接口冲突。
//这就需要我们必须在实现类中重写此方法
s.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2(){
System.out.println("SubClass:上海");
}
public void method3(){
System.out.println("SubClass:深圳");
}
//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
public void myMethod(){
method3();//调用自己定义的重写的方法
super.method3();//调用的是父类中声明的
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
}
public class SuperClass {
public void method3(){
System.out.println("SuperClass:北京");
}
}
public interface CompareB {
default void method3(){
System.out.println("CompareB:上海");
}
}
内部类
/*
* 类的内部成员之五:内部类
* 1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
*
* 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
*
* 3.成员内部类:
* 一方面,作为外部类的成员:
* >调用外部类的结构
* >可以被static修饰
* >可以被4种不同的权限修饰
*
* 另一方面,作为一个类:
* > 类内可以定义属性、方法、构造器等
* > 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
* > 可以被abstract修饰
*
*
* 4.关注如下的3个问题
* 4.1 如何实例化成员内部类的对象
* 4.2 如何在成员内部类中区分调用外部类的结构
*
*/
public class InnerClassTest {
public static void main(String[] args) {
//创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黄鹂");
}
}
class Person{
String name = "小明";
int age;
public void eat(){
System.out.println("人:吃饭");
}
//静态成员内部类
static class Dog{
String name;
int age;
public void show(){
System.out.println("卡拉是条狗");
// eat();
}
}
//非静态成员内部类
class Bird{
String name = "杜鹃";
public Bird(){
}
public void sing(){
System.out.println("我是一只小小鸟");
Person.this.eat();//调用外部类的非静态属性
eat();//同上
System.out.println(age);
}
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
public void method(){
//局部内部类
class AA{
}
}
{
//局部内部类
class BB{
}
}
public Person(){
//局部内部类
class CC{
}
}
}
开发中局部内部类的使用
public class InnerClassTest1 {
//开发中很少见
public void method(){
//局部内部类
class AA{
}
}
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}