-记住:java中所有的类,都直接或者间接继承Object类
Object类是所有类的跟类。
class A extends Object{
}
class B extends A{
}
package com.momo.test;
public class Demo8 {
public static void main(String[] args) {
//接口多态
Inter i = new InterImp();
/* System.out.println(i.a); // i.a = 55;无法为最终变量a分配值 System.out.println(i.a); System.out.println(i.b);*/ //说明了 其实还有一个默认修饰符 static System.out.println(Inter.a); System.out.println(Inter.b); }
}
interface Inter{
int a = 5;//实际上不是一个变量,默认修饰符 final
final int b = 6;
public static final int c = 7;
//接口中的成员变量有默认修饰符 public static final ,接口中的成员变量只能是静态的常量
}
class InterImp extends Object implements Inter{
}
1,类,抽象类,接口 之间的关系和作用
-类和类:继承关系 ,只能单继承,可以多层继承
-类和接口:实现关系,可以单实现,也可以多实现
-接口和接口:继承关系,可以单继承,也可以多继承
package com.momo.demo;
public class Demo1 {
public static void main(String[] args) {
A a = new C();
a.show();
// a.show2();
B b = new C(); // b.show(); b.show2(); /* C c = new C(); c.show(); c.show2();*/ }
}
interface A{
public abstract void show();
}
interface B{
public abstract void show2();
}
interface D extends A,B{
}
class C implements A,B{
@Override public void show() { System.out.println("aaaaa"); } @Override public void show2() { System.out.println("bbbbbbbbbb"); }
}
2,抽象类和接口的区别
-成员区别
抽象类:
成员变量:变量,常量
构造方法:有
成员方法:抽象,非抽象
接口:
成员变量:静态常量
构造方法:没有
成员方法:抽象
-关系区别:
上面刚讲过
-设计区别
抽象类:被继承的,体现的是is a关系
定义的是该继承体系结构中的共性内容
接口:被实现的,体现的是like a关系
定义的是该继承体系结构中的扩展功能
3,接口练习
-猫狗案例,加入额外的扩展功能(钻火圈)
分析:从具体到抽象
猫:
姓名,年龄
无参,带参
get,set,show,eat,catchMouse
狗:
姓名,年龄
无参,带参
get,set,show,eat,lookDoor
有共性内容提取父类 抽象的动物类 动物: 姓名,年龄 无参,带参 get,set,show,eat(不同动物吃的不一样,这个是抽象的) 猫继承动物 重写eat,catchMouse 狗继承动物 重写eat,lookDoor 钻火圈是扩展的,定义一个接口 接口: 钻火圈 部分猫:实现接口 部分狗:实现接口 实现:从抽象到具体 使用:具体类
package com.momo.demo;
public class Demo2 {
public static void main(String[] args) {
}
}
interface AnimalInterface{
public abstract void fireCircle();
}
abstract class Animal{
private String name;
private int age;
public Animal() { } public Animal(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract void eat(); public void show(){ System.out.println(name+"-----"+age); }
}
class Cat extends Animal{
public Cat() {
}
public Cat(String name, int age) { super(name,age); } public void eat(){ System.out.println("??吃??"); } public void catchMouse(){ System.out.println("??抓??"); }
}
class Dog extends Animal{
public Dog() {
}
public Dog(String name, int age) { super(name,age); } public void eat(){ System.out.println("??吃??"); } public void lookDoor(){ System.out.println("??看??"); }
}
class FireCat extends Cat implements AnimalInterface{
public FireCat() {
}
public FireCat(String name, int age) { super(name,age); } @Override public void fireCircle() { System.out.println("火猫"); }
}
class FireDog extends Dog implements AnimalInterface{
public FireDog() {
}
public FireDog(String name, int age) { super(name,age); } @Override public void fireCircle() { System.out.println("火狗"); }
}
-老师和学生,加入额外抽烟,喝酒等功能
-我们有音乐老师,舞蹈老师,音乐学员,舞蹈学员
为了去小日子比赛舞蹈,所有和舞蹈相关的人员需要学习日语
请使用所学知识分析并实现这个案例,测试。
一,形式参数和返回值问题的深入研究
1,形式参数
-基本类型:
-引用类型:
类:该类的具体对象
抽象类:该抽象类的具体子类对象
接口:该接口的具体实现类对象
package com.momo.demo;
public class Demo3 {
public static void main(String[] args) {
//调用PersonDemo中的method方法
PersonDemo pd = new PersonDemo();
//com.momo.demo.Person是抽象的; 无法实例化
// Person p = new Person();
//抽象类多态
Person p = new Tea();
pd.method(p);
}
}
abstract class Person{
public abstract void study();
}
class PersonDemo{
public void method(Person p){
//Person p = new Tea(); 多态
p.study();
}
}
class Tea extends Person{
@Override
public void study() {
System.out.println("学习谈恋爱。。。");
}
}
package com.momo.demo;
public class Demo4 {
public static void main(String[] args) {
InterDemo id = new InterDemo();
Inter i = new InterImp();
id.fun(i);
}
}
interface Inter{
public abstract void show();
}
class InterImp implements Inter{
@Override public void show() { System.out.println("aaaaaaa"); }
}
class InterDemo{
public void fun(Inter i){
//Inter i = new InterImp();
i.show();
}
}
2,返回值类型
-基本类型:
-引用类型:
类:返回该类的具体对象
抽象类:返回该抽象类的具体子类对象
接口:返回该接口的具体实现类对象
package com.momo.demo;
public class Demo5 {
public static void main(String[] args) {
StuDemo sd = new StuDemo();
Stu stu = sd.getStu();
stu.show();
}
}
class Stu{
public void show(){
System.out.println("好好学习,挣钱,娶媳妇。。。");
}
}
class StuDemo{
public Stu getStu(){
/Stu s = new Stu();return s;/
return new Stu();
}
}
package com.momo.demo;
public class Demo6 {
public static void main(String[] args) {
PeoPleDemo pp = new PeoPleDemo();
People p = pp.getPeople();
p.show();
}
}
abstract class People{
abstract void show();
}
class Doctor extends People{
@Override void show() { System.out.println("sdfdsfsd"); }
}
class PeoPleDemo{
public People getPeople(){
/People p = new Doctor();return p;/
return new Doctor();
}
}
package com.momo.demo;
public class Demo7 {
public static void main(String[] args) {
InDemo id = new InDemo();
In in = id.getIn();//new Tt();
in.hobby();
}
}
interface In{
void hobby();
}
class Tt implements In{
@Override public void hobby() { System.out.println("爱钱,爱车,爱美女。。"); }
}
class InDemo{
public In getIn(){
In i = new Tt();
return i;
}
}
3,链式编程
public class Demo7 {
public static void main(String[] args) {
InDemo id = new InDemo();
In in = id.getIn();//new Tt();
in.hobby();
//链式编程:代码的写法而已 //当我们调用方法返回一个对象的时候,我们还要继续调用这个对象的其他方法,这个时候我们可以不用接收 //直接再方法后继续用点调用方法 id.getIn().hobby(); new InDemo().getIn().hobby(); }
}
二,包
1,文件夹
2,作用
-分类存储
-区分同名文件
3,包的划分
-基本划分:
按照模块分
学生 com.momo.stu
老师 com.momo.tea
按照功能份
增 com.momo.add
删 com.momo.delete
改 ..
查
按照类型分
com.momo.demo
com.momo.interface
...
-高级划分:
做项目时分的很细致
4, 包的定义和注意
-定义格式:
package 包名;
多级包用 . 隔开
-注意:
package语句必须是第一条语句
package语句一个文件中只能有一个
5,带包的编译和运行
package com.momo.demo;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
javac编译的时候带上-d 路径 文件名.java javac -d . HelloWorld.java java运行时带包运行 java 包名 字节码文件名 java com.momo.demo.HelloWorld
6, 不同包下类之间的访问
-需要声明这个类是来自那个路径下,每次都要声明,太麻烦了
所以java就提供了导包语句
package com.momo.demo;
import com.momo.pojo.Bbb;
public class Demo8 {
public static void main(String[] args) {
/* Aaa a = new Aaa();
a.show();//
com.momo.domain.Bbb b2 = new com.momo.domain.Bbb();
com.momo.domain.Bbb b3 = new com.momo.domain.Bbb();
b.fun();*/
Bbb b = new Bbb(); }
}
7,导包
-不同包下类之间的访问需要声明这个类是来自那个路径下,
每次都要声明,太麻烦了所以java就提供了导包语句
-格式:
import 包名;
一般导入到类名级别
也可以写*,不建议
-注意:
package,import,class 顺序和次数问题
package > import >class
package只能有一个
import 可以有多个
class 也可以有多个,但是建议只写一个
package com.momo.demo;
import com.momo.pojo.Bbb;
import java.util.Scanner;
import java.util.*;
public class Demo8 {
public static void main(String[] args) {
/* Aaa a = new Aaa();
a.show();//
com.momo.domain.Bbb b2 = new com.momo.domain.Bbb();
com.momo.domain.Bbb b3 = new com.momo.domain.Bbb();
b.fun();*/
Bbb b = new Bbb(); Scanner sc = new Scanner(System.in); }
}
8,权限修饰符
-public protected 默认 private
-不同包下的访问
本类 同一个包下子类和无关类 不同包下的子类 不同包下无关类
private y n n n
默认 y y n n
protected y y y n
public y y y y
package com.momo.test;
public class Fu {
private void show(){
System.out.println("aaa");
}
void show2(){ System.out.println("bbb"); } protected void show3(){ System.out.println("ccc"); } public void show4(){ System.out.println("ddd"); } public static void main(String[] args) { Fu f = new Fu(); f.show(); f.show2(); f.show3(); f.show4(); }
}
package com.momo.test;
public class Zi extends Fu{ public static void main(String[] args) { Fu f = new Fu(); // f.show();how() 在 com.momo.test.Fu 中是 private 访问控制 f.show2(); f.show3(); f.show4(); System.out.println("-----------"); Zi z = new Zi(); // z.show();找不到符号 z.show2(); z.show3(); z.show4(); } }
package com.momo.test;
public class Demo1 { public static void main(String[] args) { Fu f = new Fu(); // f.show(); 在 com.momo.test.Fu 中是 private 访问控制 f.show2(); f.show3(); f.show4(); } }
package com.momo.demo;
import com.momo.test.Fu;
public class Zi extends Fu {
public static void main(String[] args) {
Fu f = new Fu();
// f.show();
// f.show2();
// f.show3();
f.show4();
System.out.println("--------------");
Zi z = new Zi(); // z.show(); // z.show2(); z.show3(); z.show4(); }
}
package com.momo.demo;
import com.momo.test.Fu;
public class Demo9 {
public static void main(String[] args) {
Fu f = new Fu();
//f.show();
// f.show2();
// f.show3();
f.show4();
}
}
9,类以及成员可以使用的修饰符以及组合
-权限修饰符:private 默认 protected public
-状态修饰符:static final
-抽象修饰符:abstract
-类:
权限修饰符:默认 public
状态修饰符:final
抽象修饰符:abstract
用的最多的是public
-成员变量
权限修饰符:private 默认 protected public
状态修饰符:static final
用的最多的是private
-构造方法
权限修饰符:private 默认 protected public
用的最多的是public
-成员方法:
权限修饰符:private 默认 protected public
状态修饰符:static final
抽象修饰符:abstract
用的最多的是public
-除此以外的常用组合
public static final
public static
public abstract
public final
package com.momo.test;
//此处不允许使用修饰符protected
// 此处不允许使用修饰符private
//此处不允许使用修饰符static
final class Aaa {
//public Aaa(){}
// Aaa(){}
// protected Aaa(){}
// private Aaa(){}
//static Aaa(){}此处不允许使用修饰符static
// final Aaa(){}此处不允许使用修饰符final
//abstract Aaa();此处不允许使用修饰符abstract
public int a; int b; protected int c; private int d; static int e; final int f = 5;
// abstract int ff = 5;此处不允许使用修饰符abstract
public static void main(String[] args) { }
}
三,内部类
1,概述
-把一个类定义在另一个类的内部,这个被定义在内部的类就叫做内部类
2,分类
-成员内部类
class A{
class B{}//成员内部类
}
-局部内部类
class A{
public void show(){
class B{}//局部内部类
}
}
3,成员内部类
-外界创建对象的格式:
外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
-访问特点:
可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
package com.momo.test;
public class Demo2 {
public static void main(String[] args) {
//我要使用Inner类中的show方法
//找不到符号
/* Inner in = new Inner();
in.show();*/
//创建格式: 外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
Outer.Inner oi = new Outer().new Inner();
oi.show();
Outer o = new Outer(); o.fun(); }
}
class Outer{
private int a = 5;
/*
* 可以认为Inner是Outer的一个成员变量,只不过类型是class类型。
* 成员变量是随着对象的创建才存在
* */
class Inner{
private int b = 6;
public void show(){
System.out.println(a);
System.out.println(b);
}
}
public void fun(){ System.out.println(a); Inner i = new Inner(); System.out.println(i.b); i.show(); //System.out.println(b);找不到符号 }
}
4,成员内部类的常用修饰符
-上面案例演示了成员内部类,但是一般我们不会像那样使用
因为我之所以把一个类写在另一个类的内部,其实就是为了保护它,
就是不想让外部直接访问它。
比如:人的身体和心脏 电脑和cpu
-成员内部类常用的修饰符有
private 为了保护他的安全
static 为了数据的访问方便
被静态修饰的成员内部类只能访问外部类的静态成员
内部类被静态修饰后的方法
静态
非静态
package com.momo.test;
public class Demo3 {
public static void main(String[] args) {
//com.momo.test.Body.Heart 在 com.momo.test.Body 中是 private 访问控制
//Body.Heart bh = new Body().new Heart();
//bh.show();
Body b = new Body(); // b.fun("老师"); b.fun("医生"); }
} class Body{ private class Heart{ public void show(){ System.out.println("展示心脏。。。"); } } public void fun(String type){ if(type.equals("医生")){ Heart h = new Heart(); h.show(); }else{ System.out.println("对比起,不能给你展示。。。"); } } }
package com.momo.test;
public class Demo4 {
public static void main(String[] args) {
// Out.In oi = new Out().new In();
//成员内部类用static修饰之后的创建方式:
//格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
/* Out.In oi = new Out.In();
oi.show();
oi.show2();*/
Out.In.show2(); }
}
class Out{
private int a = 5;
private static int b = 6;
static class In{ // int a = 55; // static int b = 66; public void show(){ // System.out.println(a);//无法从静态上下文中引用非静态 变量 a System.out.println(b); } public static void show2(){ // System.out.println(a);//无法从静态上下文中引用非静态 变量 a System.out.println(b); } }
}
package com.momo.test;
/*
- 在输出语句中补代码,可以输出 7 6 5
- Outt.this 可以限定this所表示的对象
- */
public class Demo5 {
public static void main(String[] args) {
Outt.Inn oi = new Outt().new Inn();
oi.show();
}
}
class Outt{
int a = 5;
class Inn{
int a = 6;
public void show(){
int a = 7;
System.out.println(a);
System.out.println(this.a);
// System.out.println(new Outt().a);
System.out.println(Outt.this.a);
}
}
}
5,局部内部类
-可以直接访问外部类的成员,包括私有
-外部类使用内部类成员,需要在局部位置创建内部类对象,来使用内部类中的功能
package com.momo.demo;
public class Demo11 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
class Outer{
private int a = 5;
public void method(){ /* * 在方法中,可以看做是局部变量,是随着方法的调用才存在 * */ class Inner{ public void show(){ System.out.println(a); } } Inner i = new Inner(); i.show(); }
}
-局部内部类访问局部变量的注意事项:
当局部内部类访问了局部变量,局部变量就会常量,系统会自动加上final
关键字,不能重新赋值
如果局部内部类不访问局部变量,局部变量还是变量,可以重新赋值
为什么?
因为局部变量会随着方法的调用完毕而消失,
而堆内存中创建的对象不会马上消失,而且还在使用这个变量值。
为了让数据还能继续被使用,系统就会用final修饰该变量。
这样之后这个值就会被保存下来,对象就可以继续使用。变量该消失就可以消失
package com.momo.demo;
public class Demo11 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
class Outer{
private int a = 5;
public void method(){ int b = 6; System.out.println(b); //final int b = 6; /*b = 66; System.out.println(b);*/ /* * 在方法中,可以看做是局部变量,是随着方法的调用才存在 * */ class Inner{ public void show(){ System.out.println(a); /* * 从内部类引用的本地变量必须是最终变量或实际上的最终变量 * */ System.out.println(b); // b = 66;从内部类引用的本地变量必须是最终变量或实际上的最终变量 // System.out.println(b); } } Inner i = new Inner(); i.show(); }
}
6,匿名内部类
-就是内部类的简化写法
-前提:有一个类或者接口
类可以是具体类,也可以是抽象类
-格式:
new 类名或者接口名(){重写方法}
-本质:
是一个继承了类或者实现了接口的具体子类(实现类)匿名对象
package com.momo.demo;
public class Demo12 {
public static void main(String[] args) {
/Inte i = new InteImp();i.hobby();/
new Inte(){ @Override public void hobby() { System.out.println("很爱钱 。。。"); } }.hobby(); }
}
interface Inte{
void hobby();
}
/*
class InteImp implements Inte{
@Override
public void hobby() {
System.out.println("爱钱");
}
}*/
package com.momo.demo;
public class Demo12 {
public static void main(String[] args) {
/* Inte i = new InteImp();
i.hobby();
i.show();//
@Override
public void hobby() {
System.out.println("很爱钱 。。。");
}
public void show() { System.out.println("aaaa"); } }.hobby(); new Inte(){ @Override public void hobby() { System.out.println("很爱钱 。。。"); } public void show() { System.out.println("aaaa"); } }.show();*/ //多态方式接收 Inte it = new Inte(){ @Override public void hobby() { System.out.println("很爱钱 。。。"); } public void show() { System.out.println("aaaa"); } }; it.show(); it.hobby(); }
}
interface Inte{
void hobby();
void show();
}
/*
class InteImp implements Inte{
@Override
public void hobby() {
System.out.println("爱钱");
}
@Override public void show() { System.out.println("aaaa"); }
}
*/
7,匿名内部类在实际开中的应用
-就是在我们方法参数是引用类型(类,抽象类,接口)的时候使用
在方法的返回值类型是引用类型(类,抽象类,接口)的时候使用
-可以当作具体的参数来传递,可以当作具体的返回值来返回
package com.momo.demo;
public class Demo13 {
public static void main(String[] args) {
StudentDemo sd = new StudentDemo();
sd.fun(new Student() {
@Override
public void show() {
System.out.println("aaa");
}
});
Student ss = sd.getStudent(); ss.show(); }
}
interface Student{
void show();
}
class StudentDemo{
public void fun(Student s){
s.show();
}
public Student getStudent(){ return new Student() { @Override public void show() { System.out.println("bbbb"); } }; }
}
package com.momo.demo;
public class Demo13 {
public static void main(String[] args) {
StudentDemo sd = new StudentDemo();
/* sd.fun(new Student() {
@Override
public void show() {
System.out.println("aaa");
}
});*/
//lamada表达式 可以简化 匿名内部类 /* * 语法: (..)->{方法体} * */ sd.fun(() -> System.out.println("aaa")); Student ss = sd.getStudent(); ss.show(); }
}
interface Student{
abstract void show();
}
/*class Xxx implements Student{
@Override
public void show() {
}
}*/
class StudentDemo{
public void fun(Student s){
s.show();
}
public Student getStudent(){ /* return new Student() { @Override public void show() { System.out.println("bbbb"); } };*/ return () -> System.out.println("bbbb"); }
}
--
package com.momo.demo;
public class Demo14 {
public static void main(String[] args) {
new Aa(){
@Override
public void fun(int a) {
System.out.println(a);
}
}.fun(555);
((Aa) a -> System.out.println(a)).fun(555); System.out.println(new Bb() { @Override public int sum(int a, int b) { return a + b; } }.sum(3, 4)); System.out.println(((Bb) (a, b) -> a + b).sum(3, 4)); }
}
interface Aa{
void fun(int a);
}
interface Bb{
int sum(int a,int b);
}
package com.momo.demo;
/*
- 按要求补代码
- 执行测试类后可以输出 我爱钱。。。
- / public class Demo15 { public static void main(String[] args) { Outerr.method().show(); /
* Outerr.method() 可以分析出
* method()是一个静态方法,而且应该返回的是一个Interr类型的对象
* Interr 是一个接口,应该返回的是该接口的具体实现类对象
* Outerr.method().show(); 分析出
* 调用show方法要输出我爱钱, 将来重写这个show方法
* 题目要求只能在Outerr类中补代码,所以Outer中的静态method方法
* 返回的因该是Interr接口的具体实现类对象,我们讲过的匿名内部类的本质
* 刚好就是它,
* */
}
}
interface Interr{
void show();
}
class Outerr{
//补代码
public static Interr method(){
return new Interr() {
@Override
public void show() {
System.out.println("我爱钱。");
}
};
}
}
四,Debug高级调式
1,作用
-调试程序,查看程序的执行流程
2,如何使用debug高级调式
-断点
程序中的一个标记,表示从哪里开始查看程序执行流程
-如何设置断点
在语句的最左边点击即可
-在哪里设置断点
目前:在每个方法的第一条语句上都设置
以后:哪里不会点哪里
-如何运行断点程序
代码区右键,debug ...
-看哪些地方
代码区:看当前执行到哪一行代码
控制台:看到代码执行到这句的时候的结果
debugger:看到代码目前执行到哪里,还可以看到程序中变量的变化
点击step over 可以一行一行查看代码的执行流程
-如何去除断点
再次点击即可