面向对象中常见的问题与处理方法2
目录
1.形式参数和返回值的问题
(1)形式参数:
类名:需要该类的对象
抽象类名:需要该类的子类对象
接口名:需要该接口的实现类对象
(2)返回值类型
类名:返回的是该类的对象
抽象类名:返回的是该类的子类对象
接口名:返回的是该接口的实现类对象
(3)链式编程
对象.方法1().方法2()…方法n();
这种用法:其实在方法1()调用完毕后,应该返回一个对象
方法2()调用完毕后,应该返回一个对象。
方法n()调用完毕后,可能是对象,也可能不是对象
2.包
(1)其实就是文件夹
(2)作用:
A:区分同名的类
B:对类进行管理
a:按照功能分
b:按照模块分
(3)包的定义
package 包名;
多级包用.隔开。
(4)注意事项:
A:package语句必须在文件中的第一条有效语句
B:在一个Java文件中,只能由一个paackage
C:如果没有package,那么就默认是无包名
(5)带包的编译和运行
A:手动
B:自动
java -d . helloword.java
3.导包
(1)我们多次使用一个带包的类,非常麻烦,这个时候Java就提高了一个关键字import
(2)格式:
import 包名…类名;
另一种:
import 包名…*;(不建议)
(3)package,import,class的顺序
pcakage>import>class
4.权限修饰符
(1)权限修饰符
本类 同一个包下 不同包下的子类 不同包下的无关类
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
一般使用public权限最大
5.常见的修饰符
(1)分类:
权限修饰符:private,默认,protected,public
状态修饰符:static,final
抽象修饰符:abstract
(2)常见的类及组成的修饰
类:
默认,public,final,abstract
常用的:public
成员变量:private,默认,protected,public,static,final
常用的是:private
构造方法:private,默认,protected,public,
常用的:public
成员方法:private,默认,protected,public,static,final,abstract
常用的:public
(3)另外比较常见的:
public static final int x = 10;
public static void show(){}
public final void show(){}
public abstract void show();
6.内部类:
(1)把类定义在另一个类的内部,该类就被称为内部类。
举例:把类B定义在类A中,类B就被称为内部类。
(2)内部类的访问规则
A:可以直接访问外部类的成员,包括私有
B:外部类想要访问内部类成员,必须创建对象
(3)内部类的分类
A:成员内部类
B:局部内部类
(4)成员内部类
A:private为了数据的安全性
B:static为了访问的方便性
成员内部类不是静态的:
外部类名.内部类名.对象名 = new 外部类名. new内部类名();
成员内部类是静态的:
外部类名.内部类名.对象名 = new 外部类名.内部类名();
(5)局部内部类
A:局部内部类访问局部变量必须加final修饰
B:为什么?
因为局部变量使用完毕就消失了,而堆内存的数据并不会立即消失。
所以,堆内存还是用该变量,而变量没有了。
为了让该值还存在,就加final修饰
通过反编译工具,我们看到加入final值和,对呢你存直接存储的是值,而不是变量
(6)匿名内部类
A:是局部内部类的简化形式
B:前提
存在一个类或者接口
C:格式:
new 类名或者接口名(){
重写方法;
}
D:本质;
其实是继承该类或者实现接口的子类匿名对象
(7)匿名内部类在开发中的使用
我们在开发的时候,会看到抽象类,或者接口作为参数。
而这个时候,我们知道实际需要的是一个子类对象。
如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。
interface Person{
public abstract void study();
}
class PersonDemo{
piblic void method(Person p){
p.study();
}
}
class PersonTest{
public static void main(String[] args){
PersonDemo pd = new PersonDemo();
pd.method(new Person(){
public void study(){
System.out.println(“好好学习,天天向上”);
}
});
}
}
(8)匿名内部类的面试题(补齐代码)
interface Inter{
void show();
}
classs Outer{
//补齐代码
public static Inter method(){
return new Inter(){
public void show(){
System.out.println(“HelloWorld”)
}
};
}
}
class OuterDemo{
public static void main(String[] args){
Outer.method().show();//“HelloWorld”
}
}
运动员和教练案例分析
下面展示一些 内联代码片
。
//定义一个人类
abstract class Person {
private String Name;
private int Age;
public Person() {}
public Person(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 sleep() {
System.out.println("睡觉");
}
}
//运动员类
abstract class Player extends Person{
public Player() {}
public Player(String name,int age) {
super(name,age);
}
public abstract void study();
public void eat() {}
}
//定义篮球运动员
class Basketballer extends Player{
public Basketballer() {}
public Basketballer(String name,int age) {}
public void study() {
System.out.println("学习运球和投球");
}
public void eat() {
System.out.println("吃牛肉,喝牛奶");
}
}
//乒乓球运动员
class PingPanger extends Player{
public PingPanger(){}
public PingPanger(String name, int age) {
super(name,age);
}
public void study() {
System.out.println("学习发球和接球");
}
public void eat() {
System.out.println("吃大白菜,喝小米粥");
}
}
//定义教练类
abstract class Coach extends Person{
public Coach() {}
public Coach(String name, int age) {
super(name,age);
}
public abstract void teach();
}
//定义篮球教练
class BasketballCoach extends Coach{
public BasketballCoach() {}
public BasketballCoach(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("吃羊肉,喝羊奶");
}
@Override
public void teach() {
System.out.println("教运球,投篮");
}
}
//定义乒乓球教练
class PingPangCoach extends Coach implements SpeakEnglish{
public PingPangCoach() {}
public PingPangCoach(String name,int age) {
super(name,age);
}
public void eat() {
System.out.println("吃小白菜,和大米粥");
}
public void speak() {
System.out.println("教英语");
}
@Override
public void teach() {
System.out.println("教乒乓球运动员打乒乓球");
}
}
//测试
public class Interface {
public static void main(String[] args) {
//测试乒乓球运动员
PingPanger pp = new PingPanger();
pp.setName("乒乓球运动员");
pp.setAge(20);
System.out.println(pp.getName()+"---"+pp.getAge());
pp.eat();
pp.study();
pp.sleep();
//带参
PingPanger pp1 = new PingPanger("乒乓球运动员",20);
System.out.println(pp1.getName()+"---"+pp1.getAge());
pp1.eat();
pp1.study();
pp1.sleep();
//测试篮球运动员
Basketballer bb = new Basketballer();
bb.setName("蓝球运动员");
bb.setAge(20);
System.out.println(bb.getName()+"---"+bb.getAge());
bb.eat();
bb.study();
bb.sleep();
//测试乒乓球教练
PingPangCoach ppc = new PingPangCoach();
ppc.setName("乒乓球教练");
ppc.setAge(45);
System.out.println(ppc.getName()+"---"+ppc.getAge());
ppc.eat();
ppc.teach();
ppc.sleep();
//测试乒乓球教练
BasketballCoach bbc = new BasketballCoach();
bbc.setName("乒乓球教练");
bbc.setAge(45);
System.out.println(bbc.getName()+"---"+bbc.getAge());
bbc.eat();
bbc.sleep();
}
}
类名作为形式参数
/*
形式参数:
基本数据类型:需要的是该类的对象
引用数据类型:
类:(匿名对象的时候其实我们以及讲过了)
抽象类
接口
*/
class Student{
public void study(){
System.out.println("Good")
}
}
class StudentDemo{
public void method(Student s){//把ss传给s;ss = new Student()相当于Student s = new Student();
s.study();
}
}
class StudentTest{
public static void main(String[] args){
//需求:测试Student类的study()方法
Student s = new Stduent();
s.study();
//需求:测试StudentDemo类中的method()方法
StudentDemo sd = new StudentDemo();
Stduent ss = new Student();
sd.method(ss);
//匿名对象用法
new StudentDemo().method(new Student());
}
}
抽象类名作为形式参数
/*
形式参数:
基本数据类型:需要的是该类的对象
引用数据类型:
类:(匿名对象的时候其实我们以及讲过了)
抽象类:需要的是抽象类的子类对象
接口
*/
abstract class Person{
public abstract void study();
}
class PersonDemo{
public void method(person p){//将P传给p ,p = new Student(); Person p = new Student();
p.study();
}
}
//定义一个具体的学生类
class Student extends Person{
public void study(){
System.out.println("Good");
}
}
class PersonTest{
public static void main(String[] args){
//目前是没有办法使用的
//因为抽象类没有对应的具体类
//那么,我们就应该先定义一个具体类
//需求:我要使用personDemo类中的method()方法
PersonDemo pd = new PersonDemo();
Person p = new Student();
pd.method(p);
}
}
接口名作为形式参数
/*
形式参数:
基本数据类型:需要的是该类的对象
引用数据类型:
类:(匿名对象的时候其实我们以及讲过了)
抽象类:需要的是抽象类的子类对象
接口:需要的是该接口的实现类对象
*/
//定义一个爱好接口
interface Love(
public abstract void love();
)
class LoveDemo{
public void method(Love l){
l.love();
}
}
//定义具体类的接口
class Teacher implements Love{
public void love(){
System.out.println("大苏打的");
}
}
class TeacherTest{
public static void main(String[] args){
//需求:我要测试LoveDemo类中的love()方法
LoveDemo ld = new LoveDemo();
Love l = new Teacher();
ld.method(l);
}
}
类名作为返回值类型
返回值类型
基本类型;
引用类型:
类:返回的是该类的对象
抽象类:
接口:
class Student{
public void study(){
System.out.println("Good")
}
}
class StudentDemo{
public Student getStudnet(){//(如果返回值是类名,则返回值是该类的对象)
return new Student();
}
}
class StduentTest2 {
public static void main(String[] args){
//需求,我要使用Student类中额study()方法
//但是,这一次我的要求是,不要直接创建Student的对象
StudentDemo sd = new StudentDemo();
Student s = sd.getStudent();//new Student();Student s = new Student();
s.study();
}
}
抽象类名作为返回值类型
/*
返回值类型:
基本类型:
引用类型:
类:返回的是该类的对象
抽象类:返回的是该抽象类的子类对象
接口:
*/
abstract class Person{
public abstract void study();
}
class PersonDemo{
public Person getPerson(){
//person p = new Student();
//return p
return new Student();
}
}
class Student extends Person{
public void studey(){
System.out.println("Good");
}
}
class PersonTerst{
public static void main(String[] args){
//需求:测试Person类中的study()用法
PersonDemo pd = new PersonDemo();
Person p = pd.getPerson();//=new Student();Person p = new Student();多态
p.study();
}
}
接口名作为返回值
*
返回值类型:
基本类型:
引用类型:
类:返回的是该类的对象
抽象类:返回的是该抽象类的子类对象
接口:返回的是该类的实现类接口的对象
*/
interface Love{
public abstract void love();
}
class LoveDemo{
public Love getlove(){
//love l = new Teacher();
//return l;
rreturn new Teacher();
}
}
/定义具体实现接口
class Teacher implements Love{
public void love(){
System.out.println("爱爱爱");
}
}
class TeacherTest{
public static void main(String[] args){
LoveDemo ld = new LoveDemo();//等于new Teacher(); Love l = new Teacher();多态
Love l = ld.getLove();
l.ove();
}
}
链式编程
链式编程:每次调用完毕返回的是一个对象
package关键字的概述及作用
包的概述:
其实就是文件夹
作用:对类进行分类管理
包的划分:
举例:
学生的增加,删除,修改,查询
老师的增加,删除,修改,查询
以及以后可能出现的其他的类的增删改查
基本的划分:按照模板和功能分
高级的划分:以后做项目看到
包的定义及注意事项
定义包的格式:
package包名:
多级包用,分开即可
注意事项:
package语句必须是程序的第一天可执行的代码
package语句在一个java文件中只能有一个
如果没有package,默认表示无包名
四种权限修饰符的测试
权限修饰符:
本类 同一个包下(子类和无关类) 不同包下(子类) 不同包下(无关类)
private Y
默认 Y Y
protected Y Y Y
public Y Y Y Y
结论:以后想在任意访问加public
想在子类访问加protected
在同一个包下访问默认
本类访问private
类及其组成使用的常见修饰符
修饰符:
权限修饰符:private,默认的,protected,public
状态修饰符:static ,final
抽象修饰符: abstract
类:
权限修饰符:默认修饰符,public
状态修饰符;final
抽象修饰符:abstract
用的最多的是public
成员变量:权限修饰符:private,默认的,protected,public
状态修饰符:static ,final
用的最多的是private
构造方法:权限修饰符:private,默认的,protected,public
状态修饰符:static ,final
抽象修饰符: abstract
用的最多的是public
除此之外的组合规则:
成员变量:public static final
成员方法:public static
public abstract
public final
内部类概述和访问特点
内部类概述:
把定义在其他类的内部,这个类就被称为内部类
举例:在类A中定义了一个类B,类B就是内部类
内部类的访问特点:
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
class Outer{
private int num =10;
class Inner{
public void show(){
System.out.println(num);
}
}
public void method(){
Inner i = new Inner();
i.show();
}
}
class InnerClassDemo{
public static void main(String[] args){
}
}
class Inner就是内部类
内部类分类及成员内部类的直接使用
内部类的位置
按照内部类在类中定义的位置不同,可以分为如下俩种
成员位置(成员内部类)
局部位置(局部内部类)
成员内部类
外界如何创建对象
外部类名.内部类名 对象名 = 外部类对象.内部类对象
class Outer{
private int num = 10;
class Inner{
public void show(){
System.out.println(num);
}
}
}
class InnerClassDemo{
public static void main(String[] args){
//需求访问Inner类中的show()方法
//格式:外部类名.内部类吗 对象名 = 外部类对象.内部类对象();
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
成员内部类的常见修饰符及应用
成员内部的常见修饰符
private 为了保证数据的安全性
static为了让数据访问更方便
被静态修饰的成员内部类只能访问外部类的静态成员
内部类被静态修饰后的方法
static:如果成员内部的类是静态的,那么成员变量也必须是静态的
成员内部类被静态修饰后的访问方式是:
格式;外部类名.内部类名 对象名 = new 外部类名.内部类名();
成员内部类面试题
面试题:
要求请填空分别输出30,20,10
注意:
1.内部类和外部类没有继承关系
2.通过外部类名限定this对象
Out.this.***
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);
//因为没有继承关系所以不能用super
//也可以System.out.println(new Outer().num);
System.out.println(Outer.this.num);
}
}
}
class InnerClassTest{
public static void main(String[] args){
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
局部内部类访问局部变量的问题
局部内部类:
A:可以直接访问外部类成员
B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
局部内部类访问局部变量的注意事项:
必须被final修饰
为什么?
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象
并没有立马从堆内存中消失,还要使用那个变量。为了让数据还能继续被使用,
就用final修饰,这样,在堆内存里面存储的其实是一个常量值。
匿名内部类的格式和理解
匿名内部类的简化写法:
前提:存在一个类或者接口
这里可以是具体类也可以是抽象类
格式:
new 类名或者接口名(){重写方法;}
本质:
是一个继承了该类或者实现了该接口的子类匿名对象
匿名内部类的调用方法
interface Inner{
public abstract void show();
public abstract void show2();
}
class Outer{
public void method(){
//匿名内部类每次只能调一个方法很麻烦
/* new Inner(){
public void show(){
System.out.println("show");
}
}.show();
*/
//改进版:
Inner i = new Inner(){//多态
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
};
i.show();
i.show2();
}
}
class InnerDemo{
public static void main(String[] args){
Outer o = new Outer();
o.method();
}
}
匿名内部类在开发中的应用
interface Person{
public abstract void study();
}
class PersonDemo{
//接口名作为形式参数
//其实这里需要的不是接口,而是该接口的实现类的对象
public void method(Person p){
p.study();
}
}
//实现类
class Studnet implements Person{
public void study(){
System.out.println("好好学习,天天向上");
}
}
class InnerClassTest2{
public static void main(String[] args){
//测试
PersonDemo pd =new PersonDemo();
Person p = new Studnet();
pd.method(p);
//匿名内部类在开发中的使用
//匿名内部类的本质是继承类或者实现了接口的子类匿名对象
pd.method(new Person(){
public void study(){
System.out.println("好好学习,天天向上");
}
});
}
}