回顾:
1.内存管理:由JVM来管理
1)堆:所有new出来的对象(包括成员变量)
2)栈:正在调用的方法中的所有局部变量(包括参数)
3)方法区:.class字节码文件(包括方法)
2.继承:
1)代码复用
2)extends
3)父类:共有的
子类:特有的
4)子继承父后,子具有:子+父
5)单一继承
6)传递性
7)构造子之前必须先构造父类
子类构造中必须调父类构造,若没写则默认super()
若写了则不再默认提供
3.super:指代当前对象的父类对象
super.成员变量名
super.方法名()
super()
4.向上造型:
1)父类型的引用指向子类的对象
2)能点出来什么,看引用的类型
1.内存管理:由JVM来管理
1)堆:所有new出来的对象(包括成员变量)
2)栈:正在调用的方法中的所有局部变量(包括参数)
3)方法区:.class字节码文件(包括方法)
2.继承:
1)代码复用
2)extends
3)父类:共有的
子类:特有的
4)子继承父后,子具有:子+父
5)单一继承
6)传递性
7)构造子之前必须先构造父类
子类构造中必须调父类构造,若没写则默认super()
若写了则不再默认提供
3.super:指代当前对象的父类对象
super.成员变量名
super.方法名()
super()
4.向上造型:
1)父类型的引用指向子类的对象
2)能点出来什么,看引用的类型
笔记:
1.方法的重写(Overrid ):
1)发生在父子类中,方法名相同,参数列表相同,方法体不同
2)重写方法被调用时,看对象的类型
1.方法的重写(Overrid ):
1)发生在父子类中,方法名相同,参数列表相同,方法体不同
2)重写方法被调用时,看对象的类型
Student zs = new Student();
zs.name = "zhangsan";
zs.age = 25;
zs.address = "廊坊";
zs.className = "JSD1612";
zs.sayHi(); //zhangsan,25,廊坊,JSD1612
zs.name = "zhangsan";
zs.age = 25;
zs.address = "廊坊";
zs.className = "JSD1612";
zs.sayHi(); //zhangsan,25,廊坊,JSD1612
Teacher lisi = new Teacher();
lisi.name = "lisi";
lisi.age = 26;
lisi.address = "佳木斯";
lisi.salary = 6000;
lisi.sayHi(); //lisi,26,佳木斯,6000
lisi.name = "lisi";
lisi.age = 26;
lisi.address = "佳木斯";
lisi.salary = 6000;
lisi.sayHi(); //lisi,26,佳木斯,6000
Doctor ww = new Doctor();
ww.name = "wangwu";
ww.age = 28;
ww.address = "山东";
ww.level = "主治医师";
ww.sayHi(); //wangwu,28,山东
ww.name = "wangwu";
ww.age = 28;
ww.address = "山东";
ww.level = "主治医师";
ww.sayHi(); //wangwu,28,山东
class Person{
String name;
int age;
String address;
void sayHi(){
System.out.println(name+","+age+","+address);
}
}
class Student extends Person{
String className;
void sayHi(){
System.out.println(name+","+age+","+address+","+className);
}
}
class Teacher extends Person{
double salary;
void sayHi(){
System.out.println(name+","+age+","+address+","+salary);
}
}
class Doctor extends Person{
String level;
}
Person p1 = new Student();
Person p2 = new Teacher();
Tetromino o1 = new T();
Tetromino o2 = new J();
我继承了一个中餐厅:
1)继承后还是想做中餐-----------------不需要重写
2)继承后我想改为做西餐---------------需要重写
3)继承后在中餐基础之上加上西餐-------需要重写+super调
2)继承后我想改为做西餐---------------需要重写
3)继承后在中餐基础之上加上西餐-------需要重写+super调
//重写的演示
public class OverrideDemo {
public static void main(String[] args) {
/*
Aoo o1 = new Aoo();
o1.show(); //父
Boo o2 = new Boo();
o2.show(); //子
Aoo o3 = new Boo(); //向上造型
o3.show(); //子
*/
}
}
/*
* 重写要遵循"两同两小一大"原则:
* 1.两同:
* 1)方法名相同
* 2)参数列表相同
* 2.两小:
* 1)子类方法的返回值类型小于或等于父类的
* 1.1)void时,必须相等
* 1.2)基本类型时,必须相等
* 1.3)引用类型时,小于或等于
* 2)子类抛出的异常小于或等于父类的-------异常之后
* 3.一大:
* 1)子类方法的访问权限大于或等于父类的
*/
//父类大,子类小
class Coo{
void show(){}
double test(){return 0.0;}
Doo sayHi(){return null;}
Coo say(){return null;}
}
class Doo extends Coo{
//int show(){return 1;} //编译错误,void时必须相等
//int test(){return 0.0;} //编译错误,基本类型时必须相等
//Coo sayHi(){return null;} //编译错误,引用类型时必须小于或等于
public Doo say(){return null;} //小于
}
class Aoo{
void show(){
System.out.println("父类show");
}
}
class Boo extends Aoo{
void show(){
System.out.println("子类show");
}
}
2.重写与重载的区别:常见面试题
1)重写(Override):
1.1)发生在父子类中,方法名相同,参数列表相同,方法体不同
1.2)遵循"运行期"绑定,根据对象的类型来调用方法
2)重载(Overload):
2.1)发生在一个类中,方法名相同,参数列表不同,方法体不同
2.2)遵循"编译 期"绑定,根据引用的类型来绑定方法
1)重写(Override):
1.1)发生在父子类中,方法名相同,参数列表相同,方法体不同
1.2)遵循"运行期"绑定,根据对象的类型来调用方法
2)重载(Overload):
2.1)发生在一个类中,方法名相同,参数列表不同,方法体不同
2.2)遵循"编译 期"绑定,根据引用的类型来绑定方法
overriding与overloading的区别:
重载:发生在一个类中,方法名同,参数列表不同
重写:发生在父子类中,方法名同,参数列表相同
重载:发生在一个类中,方法名同,参数列表不同
重写:发生在父子类中,方法名同,参数列表相同
//重写与重载的演示
public class OverrideOverloadDemo {
public static void main(String[] args) {
Goo goo = new Goo();
Eoo o = new Foo(); //向上造型
goo.test(o); //重载看引用
}
}
class Goo{
void test(Eoo o){
System.out.println("父型参数");
o.show(); //重写看对象
}
void test(Foo o){
System.out.println("子型参数");
o.show();
}
}
class Eoo{
void show(){
System.out.println("父类show");
}
}
class Foo extends Eoo{
void show(){
System.out.println("子类show");
}
}
3.package:
package a;
class Aoo{
}
class Boo{
Aoo o = new Aoo();
}
package a;
class Aoo{
}
class Boo{
Aoo o = new Aoo();
}
package b;
class Moo{
Aoo o = new Aoo();
}
1)作用:避免类名冲突
2)包名可以有层次结构
3)类的全称: 包名.类名
4)包名建议所有字母都小写
class Moo{
Aoo o = new Aoo();
}
1)作用:避免类名冲突
2)包名可以有层次结构
3)类的全称: 包名.类名
4)包名建议所有字母都小写
包名建议:
域名反写 . 项目名称 . 模块名称 . 类名
cn.tedu . a . student .
com.taobao . a . user .
域名反写 . 项目名称 . 模块名称 . 类名
cn.tedu . a . student .
com.taobao . a . user .
import:
1)同包中的类可以直接访问
2)不同包中的类访问有两种方式:
2.1)先import声明类/引入---建议
2.2)类的全称--------------不建议
2)不同包中的类访问有两种方式:
2.1)先import声明类/引入---建议
2.2)类的全称--------------不建议
package java.util;
class Scanner{
Scanner(In){
}
int nextInt(){
}
double nextDouble(){
}
}
class Scanner{
Scanner(In){
}
int nextInt(){
}
double nextDouble(){
}
}
import java.util.Scanner;
Scanner scan = new Scanner(System.in);
int a = scan.nextInt();
double b = scan.nextDouble();
Scanner scan = new Scanner(System.in);
int a = scan.nextInt();
double b = scan.nextDouble();
4.访问控制修饰符:
1)public:公共的,任何类
2)private:私有的,本类
3)protected:受保护的,本类、子类、同包类
4)默认的:什么也不写,本类、同包类
类的访问修饰符只能是public和默认的
类中成员的访问修饰符如上4种都可以
1)public:公共的,任何类
2)private:私有的,本类
3)protected:受保护的,本类、子类、同包类
4)默认的:什么也不写,本类、同包类
类的访问修饰符只能是public和默认的
类中成员的访问修饰符如上4种都可以
封装
1.保护数据---------私有数据
2.保护程序的逻辑---公开方法
数据私有化,行为公开化
class Card{
private String cardId; //卡号
private String cardPwd; //密码
private double balance; //余额
private String cardId; //卡号
private String cardPwd; //密码
private double balance; //余额
public boolean payMoney(double money){
if(balance>=money){
balance-=money;
return true;
}else{
return false;
}
}
if(balance>=money){
balance-=money;
return true;
}else{
return false;
}
}
public boolean checkPwd(String pwd){
if(cardPwd.equals(pwd)){
return true;
}else{
return false;
}
}
if(cardPwd.equals(pwd)){
return true;
}else{
return false;
}
}
}
5.static:静态的
1)静态变量:
1.1)由static修饰
1.2)属于类的,存在方法区中,只有一份
1.3)常常通过类名点来访问
1.4)何时用:所有对象共享的数据(图片、音频、视频...)
1)静态变量:
1.1)由static修饰
1.2)属于类的,存在方法区中,只有一份
1.3)常常通过类名点来访问
1.4)何时用:所有对象共享的数据(图片、音频、视频...)
成员变量:
1)实例变量:没有static修饰,属于对象的,存在堆中
有几个对象就有几份
通过对象点来访问
2)静态变量:由static修饰的,属于类的,存在方法区中
只有一份
通过类名点来访问
2)静态方法:
2.1)由static修饰
2.2)属于类的,存在方法区中,只有一份
2.3)常常通过类名点来访问
2.4)静态方法没有隐式的this传递,
所以在静态方法中不能直接访问实例成员
2.5)何时用:方法的操作仅与参数相关而与对象无关
1)实例变量:没有static修饰,属于对象的,存在堆中
有几个对象就有几份
通过对象点来访问
2)静态变量:由static修饰的,属于类的,存在方法区中
只有一份
通过类名点来访问
2)静态方法:
2.1)由static修饰
2.2)属于类的,存在方法区中,只有一份
2.3)常常通过类名点来访问
2.4)静态方法没有隐式的this传递,
所以在静态方法中不能直接访问实例成员
2.5)何时用:方法的操作仅与参数相关而与对象无关
静态方法没有隐式的this传递,
没有this意味着没有对象,
而实例变量必须通过对象来访问,
所以静态方法中不能直接访问实例成员
例子1:
Scanner scan = new Scanner(System.in);
int a = scan.nextInt();
double b = scan.nextDouble(); //实例方法
double c = Math.random();
double d = Math.sqrt(25);
Arrays.sort(arr); //静态方法
例子2:
double d = Math.sqrt(25); //静态方法
无论m1,m2,m3,...,m100中的哪个对象,去sqrt(25),
最终的结果都是一样的,意味着与对象无关,仅与参数相关
假设sqrt()不是静态的:
Math m1 = new Math();
double d = m1.sqrt(25); //5.0
Math m2 = new Math();
double d = m2.sqrt(25); //5.0
Math m3 = new Math();
double d = m3.sqrt(25); //5.0
3)静态块:
3.1)由static修饰
3.2)属于类的,在类被加载期间自动执行,
因类只被加载一次,所以静态块也只执行一次
3.3)何时用:常常用于初始化静态资源(图片、音频、视频等)
//static的演示
public class StaticDemo {
public static void main(String[] args) {
Loo o1 = new Loo();
o1.show();
Loo o2 = new Loo();
o2.show();
System.out.println(Loo.b); //2,建议通过类名来访问
System.out.println(o1.b); //2,不建议对象来访问
Moo.test();
Noo o3 = new Noo();
Noo o4 = new Noo();
}
}
class Noo{ //演示静态块
Noo(){
System.out.println("构造方法");
}
static{
System.out.println("静态块");
}
}
class Moo{ //演示静态方法
int a;
static int b;
void show(){
System.out.println(a);
System.out.println(b);
}
static void test(){
//编译错误,静态方法没有隐式this,
//没有this意味着没有对象,
//而a必须得通过对象来访问,
//System.out.println(a);
System.out.println(b);
}
}
class Loo{ //演示静态变量
int a;
static int b;
Loo(){
a++;
b++;
}
void show(){
System.out.println("a="+a);
System.out.println("b="+b);
}
}
6.final:最终的-----单独使用应用率极低
1)修饰变量:变量不可被改变
2)修饰方法:方法不可被重写
3)修饰类:类不可被继承
//final的演示
public class FinalDemo {
public static void main(String[] args) {
}
}
final class Roo{}
//class Soo extends Roo{} //编译错误,final修饰的类不可被继承
class Too{}
final class Uoo extends Too{}
//演示final修饰方法
class Poo{
final void show(){}
void test(){}
}
class Qoo extends Poo{
//void show(){} //编译错误,final修饰的方法不可被重写
void test(){}
}
/*
* final修饰成员变量,两种方式初始化:
* 1)声明的同时初始化
* 2)构造方法中初始化
* final修饰局部变量,使用之前赋初值即可
*/
class Ooo{ //演示final修饰变量
final int a = 5;
final int b;
Ooo(){
b = 6;
}
void show(){
final int c;
//a = 55; //编译错误,final修饰的变量不可被改变
}
}