面向对象(续2)
- 方法参数类型以及返回值类型问题研究
- 权限修饰符
- 内部类
- 匿名内部类
1. 方法参数类型以及返回值类型
1.1 参数类型
1.1.1 以类名作为形式参数
当以类名作为形参时,传入的参数为该类的对象;
public class Test1 {
public static void main(String[] args) {
Animal animal = new Animal();
setAnimal(animal); //传递了一个对象
}
public static void setAnimal(Animal an){
an.eat();
}
}
class Animal{
void eat(){
System.out.println("吃饭");
}
}
1.1.2 以抽象类名作为形式参数
当抽象类作为形式参数时,传入的参数为该类的子类对象;
public class Test2 {
public static void main(String[] args) {
Student student = new Student();
setStudent(student);//传递一个People类的子类对象
}
public static void setStudent(People p){
p.eat();
}
}
abstract class People{
public abstract void eat();
}
class Student extends People{
@Override
public void eat() {
System.out.println("吃大米");
}
}
1.1.3 以接口作为形式参数
当接口作为形式参数时,传入的参数为该类的子类对象;
public class Test3 {
public static void main(String[] args) {
JavaStudy javaStudy = new JavaStudy();
javaStudy.study(); //传递一个Study的子对象
}
public static void setStudy(Study stu){
stu.study();
}
}
interface Study{
void study();
}
class JavaStudy implements Study{
@Override
public void study() {
System.out.println("学习Java");
}
}
1.2 返回值类型
1.2.1 方法中类名作为返回值类型
方法中以类名作为返回值类型,返回一个该类对象;
public class Test4 {
public static void main(String[] args) {
show().eat();
}
public static Animal1 show(){
Animal1 animal1 = new Animal1();
return animal1;
}
}
class Animal1{
void eat(){
System.out.println("吃肉");
}
}
1.2.2 方法中抽象类作为返回值类型
方法中以抽象类作为返回值类型,返回一个该类子类对象;
public class Test5 {
public static void main(String[] args) {
show().eat();
}
public static People1 show(){
Student1 student1 = new Student1();
return student1;
}
}
abstract class People1{
public abstract void eat();
}
class Student1 extends People1{
@Override
public void eat() {
System.out.println("吃黄焖鸡");
}
}
1.2.3 方法中接口作为返回值类型
方法中以接口作为返回值类型,返回一个该类子类对象;
public class Test6 {
public static void main(String[] args) {
show().study();
}
public static Study1 show(){
Study1 study1 = new JavaStudy1();
return study1;
}
}
interface Study1{
void study();
}
class JavaStudy1 implements Study1{
@Override
public void study() {
System.out.println("Study Java everyday");
}
}
1.3 package关键字
包就是文件夹,用来解决同一个路径下不能存在同名文件夹的问题;
1.4 import关键字
import俗称导包,指的是不同包下的类之间的访问;
2. 权限修饰符
2.1 种类
权限修饰符又四种:
public > protected > 默认 > private
注:结论 day10
2.2 常见修饰符
2.2.1 修饰符
- 权限修饰符: public, protected, 默认, private
- 状态修饰符:static , final
- 抽象修饰符:abstract
2.2.2 修饰类的修饰符
- 权限修饰符:默认修饰符, public
- 状态修饰符:final
- 抽象修饰符:abstract
2.2.3 修饰成员变量的修饰符
-
权限修饰符:private,默认的,protected,public
-
状态修饰符:static,final
用的最多的就是:private
2.2.4 修饰构造方法的修饰符
- 权限修饰符:private,默认的,protected,public
用的最多的就是:public
2.2.5 修饰成员方法的修饰符
- 权限修饰符:private,默认的,protected,public
- 状态修饰符:static,final
- 抽象修饰符:abstract
用的最多的就是:public
2.2.6 组合规则
-
成员变量: public static final
-
成员方法:public static, public abstract,public final
3. 内部类
3.1 概述
-
定义:所谓的内部类就是将一个类的定义放在另一个类的内部;
-
分类:按照内部类位置分类;
-
成员内部类:在成员位置定义的类;
-
局部内部类:在局部位置定义的类;
注:图参考https://blog.csdn.net/weixin_42762133/article/details/82890555
-
-
用途:间接解决类无法多继承引起的一些问题;我们可以采用内部类继承某个具体的类或者抽象的类;
3.2 成员内部类
可以使用private、default、protected、public任意进行修饰;
使用方法:
-
间接方法:在外部类的方法中,使用内部类,然后main只调用外部类的方法;
-
直接方法:
-
一般类: 类名 对象名 = new 类名();
-
成员内部类:
外部类名.内部类名 对象名 = new 外部类名.内部类名();
-
3.2.1 非静态成员内部类
引用:https://www.cnblogs.com/chiweiming/p/11219102.html
修饰符 class 外部类名{
修饰符 class 非静态内部类名{
}
}
- 非静态内部类必须寄存在一个外部类对象里;因此,如果存在一个非静态内部类对象那么一定有对应的外部类对象。非静态内部类对象单独属于外部类的某个对象;
- 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员;
- 非静态内部类不能有静态方法、静态属性和静态初始化块;
- 外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例;
成员变量访问要点:
- 内部类里方法的局部变量:变量名;
- 内部类属性:this.变量名;
- 外部类属性:外部类名.this.变量名;
public class InnerClassTest {
public static void main(String[] args) {
OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();
innerClass.show();
}
}
class OuterClass{
public int num = 10;
class InnerClass{
public int num = 20;
public void show(){
int num = 30;
System.out.println(num); //内部类里方法的局部变量
System.out.println(this.num); //内部类属性
System.out.println(OuterClass.this.num); //外部类属性
// System.out.println(new OuterClass().num); //外部类属性
}
}
}
3.2.2 静态成员内部类
修饰符 class 外部类名{
修饰符 static class 静态成员内部类名{
}
}
- 当一个静态内部类对象存在,并不一定存在对应的外部类对象;因此,静态内部类的实例方法不能直接访问外部类的实例方法;
- 静态内部类看作外部类的一个静态成员,因此,外部类的方法中可以通过“静态内部类.方法名”的方式凡哥维纳静态内部类的静态成员,通过new静态内部类()访问内部类的实例;
public class StaticInnerClassTest {
public int num = 10;
public static class StaticInnerClass{
public int num = 20;
public void show(){
int num = 30;
System.out.println(num);
System.out.println(this.num);
// System.out.println(StaticInnerClassTest.this.num);
//不能直接访问外部类变量,因为静态内部类对象不依赖外部类对象,
// 所以存在内部类对象不代表存在外部类对象
System.out.println(new StaticInnerClassTest().num);
}
3.3 局部内部类
修饰符 class 外部类名{
修饰符 返回值类型 外部类方法名(){
class 局部内部类名{
}
}
}
- 可以直接防访问外部类的成员;
- 可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能;
- 局部内部类访问所在方法的局部变量时,那么这个局部变量必须用final修饰;JDk1.8之后final会默认加上;
- 原因:
- new出来的对象在堆内存当中;
- 局部变量是跟着方法走的,在栈内存中;;
- 方法运行结束后,立刻出栈,局部变量就会立刻消失;
- 但是new出来的对象在堆当中持续存在,直到垃圾回收消失;
public class JuBuInnerClassTest {
public static void main(String[] args) {
JubuOuterClass jubuOuterClass = new JubuOuterClass();
jubuOuterClass.outerShow();
}
}
class JubuOuterClass{
public void outerShow(){
final int num = 10; //所在方法的局部变量
//作用域仅限于该方法
class JubuInnerClass{
public void innerShow(){
System.out.println(num);
}
}
JubuInnerClass jubuInnerClass = new JubuInnerClass();
jubuInnerClass.innerShow();
}
}
3.4 匿名内部类
- 概述:匿名内部类就是局部内部类的简化写法;
- 前提:存在一个类或者接口;
- 格式
new 类名或者接口名{
重写所有抽象方法;
}
- 本质:是一个继承了该类或者实现了该接口的子类匿名对象;
- 示例:
public class NiMingInnerClassTest {
public static void main(String[] args) {
//创建一个匿名内部类对象,并调用它
new InnerClass(){
@Override
public void eat() {
System.out.println("吃饭");
}
}.eat();
}
}
interface InnerClass{
public void eat();
}