面向对象
方法参数类型以及返回值类型问题研究
类名作为形式参数
- 当你以后看到一个方法的形参要一个 类 类型,你就传递一个该类的对象
public class MyTest {
public static void main(String[] args) {
//当你以后看到一个方法的形参,要一个类 类型,你就传递一个该类的对象。
Student student = new Student();//new一个Student的对象
set(student, 60);
student.show(new Student(), 80);
System.out.println(student.num);//90
}
public static void set(Student student, int num) {
student.num = num;
}
}
class Student {
int num = 20;
public void show(Student student, int num) {
student.num = num;
//this 代表那个调用者
this.num=90;
}
}
抽象类名作为形式参数
- 当你以后看到一个方法的形参要一个抽象类 类型,你就传递一个该抽象类的子类对象
public class MyTest {
public static void main(String[] args) {
//当你以后看到一个方法的形参要一个抽象类 类型,你就传递一个该类的 子类对象。
Cat cat = new Cat();
set(cat, 100);
cat.show(500);
System.out.println(cat.num);//500
}
public static void set(Animal animal, int num) {
animal.num = num;
// ((Cat) animal).num=num;
}
}
abstract class Animal {
int num = 50;
public abstract void show(int num);
}
class Cat extends Animal {
int num = 60;
@Override
public void show(int num) {
super.num = num;
this.num=num;
}
}
接口名作为形式参数
- 当你以后看到一个方法的形参要一个接口 类型,你就传递一个该接口的子类对象
public class MyTest {
public static void main(String[] args) {
//当你以后看到一个方法的形参,要一个接口 类型,你就传递一个接口的子类对象。
MyClass myClass = new MyClass();
set(myClass,400);
System.out.println(myClass.num); //400
System.out.println(MyInterface.num); //2000
}
public static void set(MyInterface myInterface,int num){
myInterface.show(num);
}
}
interface MyInterface {
public static final int num=2000;
void show(int num);
}
class MyClass implements MyInterface{
int num=2;
@Override
public void show(int num) {
this.num=num;
}
}
类名作为返回值类型
- 当你以后看到一个方法的返回值类型,是一个类 类型,你就返回一个该类的对象
public class MyTest {
public static void main(String[] args) {
Student stu = getStudent();
Student stu1 = stu.getStu();
System.out.println(stu==stu1);//true
System.out.println(stu1.num);//20
System.out.println(stu.num);//20
}
//当你以后看到一个方法的返回值类型,是一个类,类型,你就返回一个该类的对象。
public static Student getStudent() {
Student student = new Student();
student.num = 20;
return new Student();
}
}
class Student {
int num = 30;
public Student getStu() {
return this;
}
}
抽象类名作为返回值类型
- 当你以后看到一个方法的返回值类型是一个抽象类 类型,你就返回一个该抽象类的子类对象
public class MyTest {
public static void main(String[] args) {
Animal an = getAnimal();//有一个向上转型的操作
an.num = 600;
System.out.println(an.num);//600
//向下转型
Dog dog= (Dog) an;
System.out.println(dog.num);//70
//向下转型
//Dog dog = (Dog) getAnimal();
}
//当你以后看到一个方法的返回值类型,要一个抽象类 类型,你要返回一个该类的子类对象。
public static Animal getAnimal() {
Dog dog = new Dog();
dog.num=70;
return dog;
}
}
abstract class Animal {
int num=20;
}
class Dog extends Animal {
int num=100;
}
接口名作为返回值类型
- 当你看到一个方法的返回值类型是一个接口 类型,你就返回一个该接口的子类对象
public class MyTest {
public static void main(String[] args) {
MyInterface myInterface= getMyInterface();
// AA aa= (AA) getMyInterface();
System.out.println(myInterface.num);//200
System.out.println(MyInterface.num);//200 静态成员可以通过类名直接调用
}
//当你以后看到一个方法的返回值类型,要一个接口类型,你就返回一个该接口的子类对象。
public static MyInterface getMyInterface(){
return new AA();
}
}
interface MyInterface{
public static final int num=200;
}
class AA implements MyInterface{
int num=2000;
}
链式编程
//不同包下的类之间进行访问,要用 import 导包
import org.westos.demo3.Dog;
public class MyTest {
public static void main(String[] args) {
//链式编程的语法风格
/* Student stu= getStu();
Student stu2=stu.getStudent();
int add = stu2.add(20, 30);
System.out.println(add);*/
//链式编程的语法风格:当你调用完一个方法后,他返回一个对象,那你就可以紧接着打点,再去调用这个对象所属类中的方法。
// int add = getStu().getStudent().add(60, 30);
//System.out.println(add);
/* Student stu = getStu();
Student student = stu.getStudent();
student.show(1);
System.out.println(student.num);//*/
int num = getStu().getStudent().show(120).getNum();
System.out.println(num);//120
Dog dog = new Dog();
}
public static Student getStu(){
Student student = new Student();
student.num=90000;
return student;
}
}
class Student {
int num = 20;
public int getNum() {
return num;
}
public Student getStudent(){
Student student = new Student();
student.num=6000;
return student;
}
public int add(int a,int b){
return a+b;
}
public Student show(int num) {
this.num=num;
return this;
}
}
包
package关键字的概述及作用
-
包的概述:就是文件夹
-
包的作用:用来解决同一个路径下不能存在同名文件的问题(分类管理)
-
包的划分:
按照功能
按照模块
包的定义及注意事项
-
定义包的格式
package 包名;
多级包用 . 分开即可
-
定义包的注意事项
package语句必须是程序的第一条可执行的代码
package语句在一个java文件中只能有一个
如果没有package,默认表示无包名
不同包下类之间的访问
用import导包
import关键字的概述和使用
-
导包的概述
不同包下的类之间的访问,我们发现每次使用不同包下的类的时候,都需要加包的全路径。比较麻烦。这个时候,java就提供了导包的功能
-
导包格式
import 包名;
注意:
- 这种方式导入是到类的名称
- 虽然可以最后写*,但是不建议
-
package、import、class有没有顺序关系
有关系,package>import>class
- package 只能有一个
- import 可以多个
- class 可以有多个,建议一个
权限修饰符
四种权限修饰符的测试
本类 | 同一个包下(子类和无关类) | 不同包下(子类) | 不同包下(无关类) | |
---|---|---|---|---|
private | Y | |||
默认 | Y | Y | ||
protected | Y | Y | Y | |
public | Y | Y | Y | Y |
类及其组成所使用的常见修饰符
修饰符
- 权限修饰符: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
内部类
内部类概述和访问特点
内部类概述
-
把类定义在其他类的内部,这个类就被称为内部类
举例:在类A中定义了一个类B,类B就是内部类
内部类访问的特点
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
public class MyTest {
public static void main(String[] args) {
//调用内部类中的成员方法。
//创建内部类的对象的语法
Outer.Inner inner=new Outer().new Inner();
inner.neiShow();
}
}
class Outer {
int num = 10;
private int a = 20;
//定义成员内部类
//1.内部类的特点:内部类可以直接访问外部类的成员,包括私有成员。
//2.外部类不能直接方内部类的成员,要访问必须创建内部类的对象。
class Inner {
int nei = 200;
public void neiShow() {
System.out.println("内部类的成员方法");
System.out.println(num);
System.out.println(a);
System.out.println(nei);
waiShow();
waiTest();
}
public void neiTest() {
System.out.println("内部类的成员test方法");
}
}
public void waiShow() {
System.out.println("外部类的成员方法");
}
private void waiTest() {
System.out.println("外部类私有的成员方法");
}
public void hehe(){
Inner inner = new Inner();
System.out.println(inner.nei);
inner.neiTest();
}
}
内部类分类及成员内部类的直接使用
-
按照内部类的位置分类
成员位置:在成员位置定义的类被称为成员内部类
局部位置:在局部位置定义的类,被称为局部内部类
-
成员内部类
如何在测试类中直接访问内部类的对象
格式: 外部类名.内部类名 对象名=外部类对象.内部类对象;
public class MyTest {
public static void main(String[] args) {
//内部类:将类A 定义到类 B 中,那么这个类A 就称之为内部类,类B 可以称之为外部类。
//根据内部类定义的位置不同分为:成员内部类和局部内部类。
//成员内部类:就是把内部类,定义到外部类的成员位置(类中方法外)
//局部内部类:就是把内部类,定义到外部类的局部位置(方法中)
}
}
class B {
//成员内部类
class A {
}
public void show() {
//局部内部类
class C {
}
}
}
成员内部类的常见修饰符及应用
-
成员内部类的修饰符:
private 为了保证数据的安全性
static 为了方便访问数据
注意事项:
- 静态内部类访问的外部类数据必须用静态修饰
- 成员方法可以是静态的也可以是非静态的
-
成员内部类被静态修饰后的访问方式是:
格式: 外部类名.内部类名 对象名 = new 外部类名.内部类名();
public class MyTest {
public static void main(String[] args) {
//私有的内部类,外界无法创建其对象。
//创建静态内部类的语法
//Wai.Nei nei=new Wai().new Nei();
//静态内部类,只能访问外部类的静态成员,不能访问非静态成员
Wai wai = new Wai();
wai.test();
}
}
class Wai {
//内部类,可以使用private来修饰
private class Nei {
public void neiShow() {
System.out.println("内部类的方法");
}
}
public void test(){
Nei nei = new Nei();
nei.neiShow();
}
}
要求:使用已知的变量,在控制台输出30,20,10。
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num); //30
//this 代表的是内部类的对象
System.out.println(Inner.this.num); //20
System.out.println(this.num); //20
//System.out.println(new Outer().num); //10
//记住这个语法 Outer.this 代表外部类的对象。
System.out.println(new Outer().num); //10
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
局部内部类访问局部变量的问题
-
可以直接访问外部类的成员
-
可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
-
局部内部类访问局部变量必须用final修饰
局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量
为了让数据还能继续被使用,就用final修饰,这样在堆内存里面存储的其实是一个常量值
JDK1.8之后,final会默认加上,你不用手动去加,但是你要知道
匿名内部类的格式和理解
-
匿名内部类:就是局部内部类的简化写法
-
前提:存在一个类或者接口;这里的类可以是具体类也可以是抽象类
-
格式:
new 类名或者接口名(){
重写方法
};
-
本质:是一个继承了该类或者实现了该接口的子类匿名对象
public class MyTest {
public static void main(String[] args) {
//匿名内部类:他是局部内部类的一种简写形式。
//语法格式:new 接口名/类名(){重写方法}
//匿名内部类的本质:匿名内部类本质上是一个对象,是谁的对象,是实现了该接口或者继承了该抽象类的子类对象。
// A a = new A();
new MyClass(){
@Override
public void show() {
System.out.println("重写了父类的抽象方法");
}
}.show();
}
}
abstract class MyClass {
public abstract void show();
}
class A extends MyClass{
@Override
public void show() {
}
}
匿名内部类的方法调用
public class MyTest {
public static void main(String[] args) {
new MyInterface() {
@Override
public void aa() {
System.out.println("aaaaaaaaaaaaaaa");
}
@Override
public void bb() {
System.out.println("bbbbbbbbb");
}
};
new MyInterface() {
@Override
public void aa() {
System.out.println("111111aaaaaaaaaaaaaaa");
}
@Override
public void bb() {
System.out.println("11111bbbbbbbbb");
}
}.aa();
new MyInterface() {
@Override
public void aa() {
System.out.println("222111111aaaaaaaaaaaaaaa");
}
@Override
public void bb() {
System.out.println("222211111bbbbbbbbb");
}
}.bb();
//使用同一个匿名内部类,来调用两个方法。
//多态
MyInterface myInterface = new MyInterface() {
@Override
public void aa() {
System.out.println("aaaaaaaaaaaaaaa");
}
@Override
public void bb() {
System.out.println("bbbbbbbbb");
}
};
myInterface.aa();
myInterface.bb();
}
}
interface MyInterface {
void aa();
void bb();
}
匿名内部类在开发中的应用
public class MyTest {
public static void main(String[] args) {
//对于一个普通的类,我们也可以使用匿名内部类,来创建该类的子类对象。
A a = new A() {
@Override
public void show() {
super.show();
}
};
a.show();
A b = new A();
}
}
class A {
public void show() {
}
}
public class MyTest {
public static void main(String[] args) {
//匿名内部类经常可以作为参数来传递。比较方便
MyInterface myInterface = new MyInterface() {
@Override
public void aa() {
System.out.println("aaaaaaaaaaaaaaaaaa");
}
};
set(myInterface);
set(new Animal() {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
});
}
//
public static void set(MyInterface myInterface){
myInterface.aa();
}
public static void set(Animal an) {
an.eat();
}
}
interface MyInterface{
void aa();
}
abstract class Animal{
public abstract void eat();
}
public class MyTest {
public static void main(String[] args) {
Myinterface instance = getInstance();
instance.aa();
Animal instance2 = getInstance2();
instance2.sleep();
}
//匿名内部类,作为返回值来返回
public static Myinterface getInstance() {
return new Myinterface() {
@Override
public void aa() {
System.out.println("aaaaaaaaaaaaaaaaa");
}
};
}
//匿名内部类,作为返回值来返回
public static Animal getInstance2() {
Animal an = new Animal() {
@Override
public void sleep() {
System.out.println("天天睡觉");
}
};
return an;
}
}
interface Myinterface {
void aa();
}
abstract class Animal {
public abstract void sleep();
}
完