Day10JavaSE——面向对象之传参与返回值&package关键字&import关键字&内部类
文章目录
传参
类名作为形参
public class Test {
public static void main(String[] args) {
/*参数传递:
* 当一个方法的形参需要一个引用类型,你就传递一个该类的对象
* 引用类型传递,形参的改变会影响实参,因为引用类型实际上传递的是地址值*/
//在堆内存开辟一个空间,并对num进行显式初始化num=20
Student student = new Student();
//此处打印出来的是一个地址值
System.out.println(student);
System.out.println("此时堆内存内num=" + student.num);
//调用test函数,把student的地址和50传进函数
test(student, 50);
}
public static void test(Student student, int num) {
//因为操作空间相同,所以将20覆盖为50
student.num = num;
System.out.println("此时堆内存内num=" + student.num);
}
}
class Student {
int num = 20;
public void setNum(Student student, int num) {
student.num = num;
}
}
抽象类名作为形参
public class Test {
public static void main(String[] args) {
//当你看到一个方法的形参要一个抽象类,你就传该抽象类的子类对象
BB bb = new BB();
test(bb, 2000);
System.out.println(bb.num);
AA a = new BB();
test(a, 2000);
System.out.println(a.num);
}
public static void test(AA aa, int num) {
//多态形式用父类型接收子类就是多态
aa.num = num;
}
}
public abstract class AA{
int num=10;
public abstract void show(int num);
}
public class BB extends AA {
int num = 100;
@Override
public void show(int num) {
this.num = num;
//super.num=num;
}
}
public class CC extends AA {
@Override
public void show(int num) {
super.num=num;
}
}
接口名作为形参
public class Test {
public static void main(String[] args) {
//当你见到形参需要接口类型,就传递接口的子类对象
AA aa = new AA();
test(aa);
aa.show();
System.out.println(MyInterface.num);
System.out.println(AA.num);
aa.show();
}
public static void test(MyInterface myInterface) {
System.out.println(myInterface.num);
}
}
interface MyInterface {
int num = 200;
void show();
}
class AA implements MyInterface {
@Override
public void show() {
System.out.println(this.num);
}
}
返回值
类名作为返回值类型
public class Test {
public static void main(String[] args) {
//方法的返回值类型为引用类型,你就返回一个该类的对象
Student student=test(100);
int num=student.num;
System.out.println(num);
}
public static Student test(int num){
Student student = new Student();
student.num=num;
return student;
}
}
class Student{
int num=20;
}
抽象类名作为返回值类型
public class Test {
public static void main(String[] args) {
MyClass m=test(500);//父类去接子类地址为多态
System.out.println(m.num);//访问父类的num
m.show(5000);//更改子类的num
//向下转型访问子类的num
System.out.println(((MySon) m).num);
}
//当一个方法的返回值类型是一个抽象类类型,你就返回一个该抽象类的子类对象
public static MyClass test(int num){
MySon mySon = new MySon();
mySon.num=num;
return mySon;
}
}
abstract class MyClass{
int num=200;
public abstract void show(int num);
}
class MySon extends MyClass{
int num=2;
@Override
public void show(int num) {
this.num=num;
}
}
接口名作为返回值类型
public class Test {
public static void main(String[] args) {
//在这段代码里其实创建了两个堆区缓存,如下图图解
Son son = new Son();
MyInterface f=test(son);
son.show();//调用子类的show方法
System.out.println(son.num);
System.out.println(f.num);
System.out.println(((Son) f).num);
}
//当一个方法的返回值类型是一个接口类型,你就返回一个该接口的子类对象
public static MyInterface test(MyInterface myInterface) {
System.out.println(myInterface.num);//200为接口里面的常量
Son son = new Son();
son.num = 4;
return son;
}
}
interface MyInterface {
public static final int num = 200;
public abstract void show();
}
class Son implements MyInterface {
int num = 600;
@Override
public void show() {
this.num = 80000;
}
}
图解
链式编程
public class Test {
public static void main(String[] args) {
//链式编程:当你调用一个方法,这个方法返回的是一个对象
// 你就可以直接在后面打点去调用这个对象中的方法
Student s = new Student();
System.out.println(test().getStudent(s).num);
}
public static Student test(){
Student student = new Student();
return student;
}
}
class Student{
int num=20;
public Student getStudent(Student student){
this.num=num;
return student;
}
}
包
A:包的概述: 就是文件夹
B:包的作用: 用来解决同一个路径下不能存在同名文件的问题(分类管理)
C:包的划分:
按照功能
按照模块
包的定义及注意事项
A:定义包的格式
package 包名;
多级包用.分开即可
B:定义包的注意事项
A:package语句必须是程序的第一条可执行的代码
B:package语句在一个java文件中只能有一个
C:如果没有package,默认表示无包名
package org.west.Demo;
不同包下类之间的访问
import 包名;导入到类的名称。用谁导谁
多级包之间用.衔接
import关键字概述&使用
A:导包的概述
不同包下的类之间的访问,我们发现,每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能
B:导包格式
import 包名;
注意:
这种方式导入是到类的名称。
虽然可以最后写*,但是不建议。
C:package,import,class有没有顺序关系(面试题)
有顺序关系,package---->import---->class
package只能有一个
import可以有多个
class最好一个java文件里只有一个
内部类
概述
把类定义在其他类的内部,这个类就被称为内部类
即在A类中定义了一个B类,B类就是内部类,A就是外部类
内部类的访问特点
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
内部类访问
public class Test {
public static void main(String[] args) {
//Wai.Nei n=new Wai().new Nei();
// 由于内部类私有,所以只能在外部类中调用内部类,此语法失效
//要想访问内部类,需要在外部类中构建方法,去从外部类中访问内部类
//创建外部类对象通过外部类的成员方法去访问外部类
Wai wai = new Wai();
wai.waiShow();
wai.wai();
}
}
class Wai{
int num=30;
private int num2=300;
public void waiShow(){
System.out.println("wai show");
}
private void waiTest(){
System.out.println("外部类私有方法");
}
//定义成员内部类
//内部类可以直接访问外部类的成员包括私有
//private 可以修饰内部类 私有的内部类,外界不能创建其对象
private class Nei{
int num3=400;
public void neiShow(){
//内部类可以随意访问外部类的成员,包括私有的
System.out.println(num);
System.out.println(num2);
System.out.println(num3);
waiShow();
waiTest();
}
}
public void wai(){
Nei n= new Nei();
System.out.println(n.num3);
n.neiShow();
}
}
静态的内部类访问
public class MyTest {
public static void main(String[] args) {
//Wai.Nei nei = new Wai().new Nei();
//静态内部类的创建语法是如下:
Wai.Nei nei2=new Wai.Nei();
nei2.neiShow();
}
}
class Wai {
private int num = 100;
private static double d=3.25;
public void waiShow() {
System.out.println("waishow");
}
public static void waiShow2() {
System.out.println("waishow");
}
//内部类可以使用static来修饰
//静态内部类,只能访问外部类的静态成员
public static class Nei {
int c = 20;
public void neiShow() {
//System.out.println(num);
// waiShow();
System.out.println(d);
waiShow2();
}
}
}
私有的内部类访问
public class Test {
public static void main(String[] args) {
//Wai.Nei n=new Wai().new Nei();
// 由于内部类私有,所以只能在外部类中调用内部类,此语法失效
//要想访问内部类,需要在外部类中构建方法,去从外部类中访问内部类
//创建外部类对象通过外部类的成员方法去访问外部类
Wai wai = new Wai();
wai.waiShow();
wai.wai();
}
}
class Wai{
int num=30;
private int num2=300;
public void waiShow(){
System.out.println("wai show");
}
private void waiTest(){
System.out.println("外部类私有方法");
}
//定义成员内部类
//内部类可以直接访问外部类的成员包括私有
//private 可以修饰内部类 私有的内部类,外界不能创建其对象
private class Nei{
int num3=400;
public void neiShow(){
//内部类可以随意访问外部类的成员,包括私有的
System.out.println(num);
System.out.println(num2);
System.out.println(num3);
waiShow();
waiTest();
}
}
public void wai(){
Nei n= new Nei();
System.out.println(n.num3);
n.neiShow();
}
}
内部类分类
成员位置:在成员位置定义的类,被称为成员内部类。
局部位置:在局部位置定义的类,被称为局部内部类。
class A{
//位于成员位置,为成员内部类
class B{
}
public void show(){
//类位于局部位置为局部内部类
class C{
}
}
}
成员内部类&常见修饰符及应用
A:如何在测试类中直接访问内部类的成员。
格式: 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
B:成员内部类的修饰符:
private 为了保证数据的安全性
static 为了方便访问数据
注意事项: a:静态内部类访问的外部类数据必须用静态修饰。
b: 成员方法可以是静态的也可以是非静态的
C:成员内部类被静态修饰后的访问方式是:
格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
案例演示
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
//局部变量的引用
System.out.println(num);
//本类的成员变量的引用
System.out.println(this.num);
//外部类的成员变量的引用
System.out.println(Outer.this.num);
}
}
}
class InnerClassTest {
/*A:面试题
要求:使用已知的变量,在控制台输出30,20,10*/
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
局部内部类
public class Test {
public static void main(String[] args) {
Wai wai = new Wai();
wai.waiTest(50);
System.out.println(wai.num);
}
}
class Wai{
int num=100;
public void waiTest(int i){
int a=200;
//定义局部内部类
//局部内部类:把一个类定义到另一个类的方法中
//内部类可以直接访问,外部类的成员,包括私有的。
//局部内部类,在外界没有直接创建其对象的语法
//可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
class Nei{
int j=20;
public void neiShow(){
num=300;
/*局部内部类访问外部局部变量,这个局部变量要加final修饰,使其变为一个常量
* JDK1.8默认将要访问的局部变量加上final,使其变成了一个常量
* 所以局部变量值在内部类中不能更改
* 这样是为了延长局部变量的周期,因为局部变量随着方法的调用完毕而消失
* 而此时局部类在堆中还存在,并且要使用这些局部变量时*/
System.out.println(num);
System.out.println(a);
System.out.println(i);
}
}
Nei nei = new Nei();
System.out.println(nei.j);
nei.neiShow();
}
}
匿名内部类
A:匿名内部类: 就是局部内部类的简化写法。
B:前提: 存在一个类或者接口;这里的类可以是具体类也可以是抽象类。
C:格式:
new 类名或者接口名(){
重写方法;
} ;
D:是一个继承了该类或者实现了该接口的子类匿名对象。
抽象类的匿名内部类
public class Test {
public static void main(String[] args) {
/* 匿名内部类:他是局部内部类的一种简化写法
* 匿名内部类的本质:匿名内部类本质上是一个对象
* 是继承了该抽象类或实现了该接口的子类匿名对象*/
//想得到一个抽象类MyClass的子类对象
// 可以创建一个子类重写MyClass的方法,再去创建子类对象
// 也可以采用匿名内部类来得到一个抽象类的子类对象
new MyClass(){
@Override
public void aa() {
System.out.println("AAAAAAAAAA");
}
}.aa();
//这块代码是对象,具有对象的一切操作,也可以new多个MyClass的对象
new MyClass(){
@Override
public void aa() {
System.out.println("AAAAAAAAAA");
}
};
}
}
abstract class MyClass{
public abstract void aa();
}
/*class AA extends MyClass{
@Override
public void aa() {
System.out.println("AAAAAAAA");
}
}*/
接口的匿名内部类
public class Test {
public static void main(String[] args) {
//这就是接口MyInterface的匿名对象
new MyInterface(){
@Override
public void bb() {
System.out.println("AAAAAAAAAAA");
}
}.bb();
/*new 类名或者接口名(){
重写方法;
} ;*/
MyInterface a = new MyInterface() {
@Override
public void bb() {
System.out.println("AAAAAAAAAAA");
}
};
a.bb();
//以上这两段代码是一样的
}
}
interface MyInterface{
void bb();
}
/*
class BB implements MyInterface{
@Override
public void bb() {
System.out.println("AAAAAAAAAAA");
}
}
*/
匿名内部类的用处
其本质是一个对象,这样就不需要去创建类,再new对象。直接去new这段代码的对象,然后对代码进行重写就可以使用。
以下是对比
public class Test {
public static void main(String[] args) {
//一般方法,先创建子类进行MyClass的方法重写
//创建子类对象,去调用重写的方法
MyClass2 myClass2 = new MyClass2();
myClass2.show();
myClass2.show1();
/*此方法过于繁琐,我们用匿名对象*/
new MyClass(){
@Override
public void show() {
System.out.println("匿名内部类重写了show");
}
@Override
public void show1() {
System.out.println("匿名内部类重写了show1");
}
}.show();
new MyClass(){
@Override
public void show() {
System.out.println("匿名内部类重写了show");
}
@Override
public void show1() {
System.out.println("匿名内部类重写了show1");
}
}.show1();
/*一个匿名对象只能引用一次方法,要想再引用就需要重新new对象
所以我们用多态去简化代码*/
MyClass mc= new MyClass(){
@Override
public void show() {
System.out.println("匿名内部类重写了show");
}
@Override
public void show1() {
System.out.println("匿名内部类重写了show1");
}
};
mc.show();
mc.show1();
}
}
abstract class MyClass {
public abstract void show();
public abstract void show1();
}
class MyClass2 extends MyClass {
@Override
public void show() {
System.out.println("子类方法重写了show");
}
@Override
public void show1() {
System.out.println("子类方法重写了show1");
}
}
public class Test {
public static void main(String[] args) {
//用创建子类对象去调用
MyInterface mif1 = new AA();
mif1.show1();
mif1.show2();
//用匿名对象去调用
MyInterface mif = new MyInterface() {
@Override
public void show1() {
System.out.println("用匿名对象将show1重写了");
}
@Override
public void show2() {
System.out.println("用匿名对象将show2重写了");
}
};
mif.show1();
mif.show2();
}
}
interface MyInterface {
void show1();
void show2();
}
class AA implements MyInterface {
public AA() {
super();
}
@Override
public void show1() {
System.out.println("用创建子类对象将show1重写了");
}
@Override
public void show2() {
System.out.println("用创建子类对象将show2重写了");
}
}
匿名内部类在开发中的应用
匿名内部类传参
public class Test {
/*问题引出
首先回顾我们曾经讲过的方法的形式参数是引用类型的情况,
我们知道这里需要一个子类对象。而匿名内部类就是一个子类匿名对象,
所以,可以使用匿名内部类改进以前的做法。*/
public static void main(String[] args) {
/*匿名内部类应用:可以作为参数来传递或作为参数返回*/
//当你看到一个方法的形参,要一个接口类型,你就可以传递一个该接口的子类对象
System.out.println("==============使用子类对象传参==============");
UU uu = new UU();
set(uu);
System.out.println("=============使用匿名内部类传参=============");
set(new DD() {
@Override
public void dd() {
System.out.println("匿名内部类传参");
}
});
System.out.println("=============使用匿名内部类传参2=============");
DD d=new DD() {
@Override
public void dd() {
System.out.println("匿名内部类传参");
}
};
set(d);
}
public static void set(DD dd) {
dd.dd();
}
}
interface DD {
void dd();
}
class UU implements DD {
@Override
public void dd() {
System.out.println("dd被用子类重写了");
}
}
匿名内部类返回值
public class Test {
public static void main(String[] args) {
MyInterFace m = test();
m.myInterFace();
}
//当你以后看到一个方法的返回值类型是一个接口类型,那你就返回一个接口的子类对象
public static MyInterFace test() {
MyInterFace my = new MyInterFace() {
@Override
public void myInterFace() {
System.out.println("匿名调用的接口的方法重写了");
}
};
return my;
}
}
interface MyInterFace {
void myInterFace();
}
public class Test {
public static void main(String[] args) {
System.out.println("=============创建子类对象===========");
MyClass m = test2();
m.myClass();
System.out.println("===========创建匿名内部类===========");
MyClass s = test();
s.myClass();
}
public static MyClass test() {
MyClass mc = new MyClass() {
@Override
public void myClass() {
System.out.println("父类的方法被以匿名对象的方式重写了");
}
};
return mc;
}
public static MyClass test2() {
//多态形式创建子类对象
MyClass mc = new SonClass();
return mc;
}
}
abstract class MyClass {
public abstract void myClass();
}
class SonClass extends MyClass {
@Override
public void myClass() {
System.out.println("父类的方法被以创建子类的方式重写了");
}
}
匿名内部类中this关键字
//A: 面试题
interface Inter {
public static final int a = 23 ;
}
public class Test {
public static void main(String[] args) {
new Inter() {
public void show() {
//this 代表匿名内部类 或者说接口的子类对象。
System.out.println(this.a);//23
}
}.show();
}
}
interface Inter {
void show();
}
class Outer {
//补齐代码,要求在控制台输出”HelloWorld”
//分析,main函数中是链式编程,需要Method方法返回一个对象
// 这个对象是接口Inter的接口对象,用匿名内部类创建
public static Inter method(){
return new Inter() {
@Override
public void show() {
System.out.println("Hello World");
}
};
}
}
public class Test {
public static void main(String[] args) {
//用类名直接调用,没有new 说明是静态的
//直接调用show,所以返回一个对象
Outer.method().show();
}
}
类中定义接口
A: 举例: 电脑类中的内存条接口
B: 定义电脑类,然后在电脑类中定义内存条接口
class Computer{
interface Neicuntiao{
}
}
四种权限修饰符的测试
A:案例演示
四种权限修饰符: private(私有的) , 默认 , protected(受保护的) , public(公共的)
B:结论
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
类及其组成所使用的常见修饰符
A:修饰符:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
B:修饰类的关键字:
权限修饰符:默认修饰符,public
状态修饰符:final
抽象修饰符:abstract
用的最多的就是:public
C:修饰成员变量的关键字:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
用的最多的就是:private
D:修饰构造方法的关键字:
权限修饰符:private,默认的,protected,public
用的最多的就是:public
E:修饰成员方法的关键字:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
用的最多的就是:public
F:除此以外的组合规则:
成员变量:public static final
成员方法:public static
public abstract
public final
例: 电脑类中的内存条接口
B: 定义电脑类,然后在电脑类中定义内存条接口
```java
class Computer{
interface Neicuntiao{
}
}
四种权限修饰符的测试
A:案例演示
四种权限修饰符: private(私有的) , 默认 , protected(受保护的) , public(公共的)
B:结论
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
类及其组成所使用的常见修饰符
A:修饰符:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
B:修饰类的关键字:
权限修饰符:默认修饰符,public
状态修饰符:final
抽象修饰符:abstract
用的最多的就是:public
C:修饰成员变量的关键字:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
用的最多的就是:private
D:修饰构造方法的关键字:
权限修饰符:private,默认的,protected,public
用的最多的就是:public
E:修饰成员方法的关键字:
权限修饰符:private,默认的,protected,public
状态修饰符:static,final
抽象修饰符:abstract
用的最多的就是:public
F:除此以外的组合规则:
成员变量:public static final
成员方法:public static
public abstract
public final