7.面向对象基础
1、 什么是对象?什么是类?说明一下类和对象的关系?
正确答案:
类(class)和对象(object)是两种以计算机为载体的计算机语言的合称。
对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型。
它们的关系是,对象是类的一个具体实例,类是对象的模板;对象的具体的,类是抽象的;
【编程题】
定义一个厨师类(Chef),并为厨师类定义制作牛肉面的重载方法cookNoodle();
关于牛肉面的参数如下;
尺寸:size (大碗还是小碗) 大碗10元,小碗8元
是否加肉:beef :加肉+5元
加蛋的数量:eggs :每个2元;
定义以下重载方法,用来输入面条的信息,同时返回牛肉面的价格;
int cookNoodle(); //默认为大碗
int cookNoodle(int size); //1为大碗,其它数字为小碗
int cookNoodle(int size,boolean beef);
int cookNoodle(int size boolean beef,int eggs);
当用户调用int money= cookeNoodle(1,true,2);时,将返回19,同时输出
你购买的面加2个蛋,加肉的大碗牛肉面;总价为19元;
public class Chef {
private int size = 1;
private boolean beef;
private int eggs;
//默认为大碗
int cookNoodle(){
int sum = 0;
if(size==1){
sum += 10;
}else{
sum+=8;
}
if(beef){
sum += 5;
}
sum += eggs*2;
return sum;
}
//1为大碗,其它数字为小碗
int cookNoodle(int size){
this.size = size;
return cookNoodle();
}
int cookNoodle(int size,boolean beef){
this.size = size;
this.beef = beef;
return cookNoodle();
}
int cookNoodle(int size,boolean beef,int eggs){
this.size = size;
this.beef = beef;
this.eggs = eggs;
return cookNoodle();
}
public static void main(String[] args) {
Chef c = new Chef();
int money = c.cookNoodle(1,true,2);
System.out.println(money);
}
}
8.构造方法与继承
1、 Java类Demo中存在方法func1、func2、func3和func4,请问该方法中,哪些是不合法的定义?( )【√】
public class Demo{
float func1()
{
int i=1;
return;
}
float func2()
{
short i=2;
return i;
}
float func3()
{
long i=3;
return i;
}
float func4()
{
double i=4;
return i;
}
}
[多选题]
A、func1 √
Dfunc4√
2.如何定义一个构造方法?构造方法的主要作用是什么?
构造方法是一个特殊的方法。
构造方法的名称与类同名,没有返回值;
每个类中都必须至少有一个构造方法,如果不定义,编译器会自动生成一个无参的构造方法;
构造方法的作用是给对象的属性赋初值;
3.编写Java程序,用于显示人的姓名和年龄。 定义一个人类(Person),该类中应该有两个私有属性,姓名(name)和年龄(age)。定义构造方法,用来初始化数据成员。再定义显示(display)方法,将姓名和年龄打印出来。 在main方法中创建人类的实例,然后将信息显示。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void display() {
System.out.println("姓名:"+name+",年龄:"+age);
}
public static void main(String[] args) {
Person p = new Person("tom",20);
p.display();
}
}
4.【编程题】构造方法与重载
为"无名的粉"写一个类:class WuMingFen 要求:
1.有三个属性:面码:String theMa 粉的份量(两):int quantity
是否带汤:boolean likeSoup
2.写一个构造方法,以便于简化初始化过程,如:
WuMingFen f1 = new WuMingFen(“牛肉”,3,true);
3.重载构造方法,使得初始化过程可以多样化:
WuMingFen f2 = new WuMingFen(“牛肉”,2);
4.如何使得下列语句构造出来的粉对象是酸辣面码、2两、带汤的?
WuMingFen f3 = new WuMingFen();
5.写一个普通方法:check(),用于查看粉是否符合要求。即:将对象的三个属性打印在控制台上。
public class WuMingFen {
//面码
String theMa ;
//分量
int quantity ;
//是否带汤
boolean likeSoup ;
public WuMingFen(String theMa, int quantity, boolean likeSoup) {
this.theMa = theMa;
this.quantity = quantity;
this.likeSoup = likeSoup;
}
public WuMingFen(String theMa, int quantity) {
super();
this.theMa = theMa;
this.quantity = quantity;
}
public WuMingFen() {
this("酸辣粉",2,true);
}
public void check() {
System.out.println("面码:"+theMa+",分量:"+quantity+",是否带汤:"+likeSoup);
}
public static void main(String[] args) {
WuMingFen f1 = new WuMingFen("牛肉",3,true);
WuMingFen f2 = new WuMingFen("牛肉",2);
WuMingFen f3 = new WuMingFen();
f1.check();
f2.check();
f3.check();
}
}
5.【编程题】类的综合练习
1、写一个名为Account的类模拟账户。该类的属性和方法如下图所示。该类包括的属性:账号id,余额balance,年利率annualInterestRate;包含的方法:访问器方法(getter和setter方法),取款方法withdraw(),存款方法deposit()。
Account
int id
double balance
double annualInterestRate
public Account (int id, double balance, double annualInterestRate )
public int getId()
public double getBalance()
public double getAnnualInterestRate()
public void setId( int id)
public void setBalance(double balance)
public void setAnnualInterestRate(double annualInterestRate)
public void withdraw (double amount)
public void deposit (double amount)
提示:在提款方法withdraw中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应给出提示。
public Customer(String f,String l)
public String getFirstName()
public String getLastName()
public Account getAccount()
public void setAccount(Account account)
a. 声明三个对象属性:firstName、lastName和account。
b. 声明一个公有构造器,这个构造器带有两个代表对象属性的参数(f和l)
c. 声明两个公有存取器来访问该对象属性,方法getFirstName和getLastName返回相应的属性。
d. 声明setAccount 方法来对account属性赋值。
e. 声明getAccount 方法以获取account属性。
3.写一个测试程序。
(1)创建一个Customer ,名字叫 Jane Smith, 他有一个账号为1000,余额为2000元,年利率为 1.23% 的账户。
(2)对Jane Smith操作。
存入 100 元,再取出960元。再取出2000元。
打印出Jane Smith 的基本信息
成功存入 :100.0
成功取出:960.0
余额不足,取款失败
Customer [Smith, Jane] has a account: id is 1000, annualInterestRate is 1.23%, balance is 1140.0
public class Account {
int id;
double balance;
double annualInterestRate;
public Account(int id, double balance, double annualInterestRate) {
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
public void withdraw (double amount) {
if(balance<amount) {
System.out.println("余额不足");
return;
}
balance-=amount;
System.out.println("成功取出:"+amount);
}
public void deposit (double amount) {
balance+=amount;
System.out.println("成功存入:"+amount);
}
}
class Customer {
String firstName;
String lastName;
Account account;
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public static void main(String[] args) {
Customer customer = new Customer("Smith","Jane");
Account account = new Account(1000, 2000, 0.0123);
customer.setAccount(account);
//操作存钱和取钱,面向客户的操作
customer.getAccount().deposit(100);
customer.getAccount().withdraw(960);
customer.getAccount().withdraw(2000);
}
}
类中的属性没有赋值,在创建对象时,系统会为对象的属性分配默认值:
byte、short、int、long类型的属性,默认值是0
float、double类型的属性,默认值是0.0
boolean类型的属性,默认值是false
char类型的属性,默认值是'\u0000'
引用类型的属性,默认值是null
3种引用类型
类class
接口interface
数组array
9.封装和多态
1、 方法重载与方法重写的区别?
正确答案: 方法重写,也叫子类的方法覆盖父类的方法,要求返回值、方法名和参数都相同。 重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同,最常见的重载的例子就是类的构造函数;
1. 构造器的作用:主要作用是用来创建对象的,次要作用可以对对象进行初始化。
2. 构造器的写法: 构造器的名字一定要和类名相同,包括大小写
[<修饰范围>] 类名 ([参数,参数...]){
语句
}
//定义一个Person类的构造器
Person(){
System.out.println("通过调用构造器,创建了一个对象");
}
Person(String s){
}
Person(String s ,int i){
}
Person(String name,char sex,int age,double height){
//既有全局变量,又有局部变量,默认使用的是局部变量
this.name = name;
this.sex = sex;
this.age = age;
this.height = height; }
3. 构造器的特点:
1. 如果一个类中没有定义构造器,那么系统会为这个类自动分配一个无参构造器;如果类中定义了构造
器,那么系统就不自动分配无参构造器了。
2. 一个类中可有多个构造器,但要保证构造器的参数列表不同,构成了构造器的重载。
简答题2
2、 访问修饰符有哪些?它们有什么区别?
您的回答: 在Java编程语言中有四种权限访问控制符,这四种访问权限的控制符能够控制类中成员的可见性。
一、public
(1)定义:public是公共的,被public所修饰的成员可以在任何类中都能被访问到。
(2)修饰的成分:
public能用来修饰类,在一个java源文件中只能有一个类被声明为public,而且一旦有一个类为public,那这个java源文件的文件名就必须要和这个被public所修饰的类的类名相同,否则编译不能通过。说到这里,穿插多一点知识。一个类作为外部类的时候只能被public或者默认访问修饰符所修饰,但是一个类如果作为内部类的时候,则可以被四种访问修饰符所修饰,因为一个类作为内部类的时候,就作为外部类的一个成员属性了,因此可以有四种访问修饰符修饰,这是内部类和外部类的一个区别。
public用来修饰类中成员(变量和方法),被public所修饰的成员可以在任何类中都能被访问到。通过操作该类的对象能随意访问public成员。
public在类的继承上的体现,被public所修饰的成员能被所有的子类继承下来。
二、protected
(1)定义:protected是受保护的,受到该类所在的包所保护。
(2)作用域:被protected所修饰的成员会被位于同一package中的所有类访问到。同时,被protected所修饰的成员也能被该类的所有子类继承下来。(注意:这里是指同一个package或者不同的package中的子类都能访问)
三、friendly(默认,缺省的)
(1)定义:friendly是友好的,即在成员的前面不写任何的访问修饰符的时候,默认就是友好的。所谓友好的,是对同一package的类友好。
(2)作用域:同一package中的所有类都能访问。被friendly所修饰的成员只能被该类所在同一个package中的子类所继承下来。(也就是说只有在同一个package中的子类才能访问到父类中friendly修饰的成员)
四、private
(1)定义:private是私有的,即只能在当前类中被访问到,它的作用域最小。 下面用一个表格说明四个访问控制符的作用域:
作用域 当前类 同一package 子孙类 其他package的类
public √ √ √ √
protected √ √ √ ×
friendly √ √ × ×
private √ × × ×
继承的编程题(略)
【编程题】继承
建立三个类:居民、成人、官员。居民包含身份证号、姓名、出生日期,
而成人继承自居民,多包含学历、职业两项数据;官员则继承自成人,
多包含党派、职务两项数据。
要求每个类的字段都以属性的方式对外提供数据输入输出的功能。
//居民
public class Person {
String sfz;
String name;
String birthday;
public String getSfz() {
return sfz;
}
public void setSfz(String sfz) {
this.sfz = sfz;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}
class Adult extends Person{
String xueLi;
String job;
public String getXueLi() {
return xueLi;
}
public void setXueLi(String xueLi) {
this.xueLi = xueLi;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
class Official extends Adult{
String dangPai;
String zhiwu;
public String getDangPai() {
return dangPai;
}
public void setDangPai(String dangPai) {
this.dangPai = dangPai;
}
public String getZhiwu() {
return zhiwu;
}
public void setZhiwu(String zhiwu) {
this.zhiwu = zhiwu;
}
}
【编程题】多态练习
定义一个Animal类,方法有sing方法,定义这个类的三个子类(Dog,Cat,Bird),
分别重写这个方法。利用多态,定义一个Animal类型的对象,
Animal a;分别引用三个子类的对象,调用sing方法。
为每个子类,增加额外的方法。通过此例,
练习upCast,downCast,及instanceof操作符。
public class Animal {
public void sing() {
System.out.println("动物唱歌");
}
}
public class Bird extends Animal{
@Override
public void sing() {
System.out.println("叽叽喳喳");
}
}
public class Cat extends Animal{
@Override
public void sing() {
System.out.println("喵喵喵");
}
public void catchMouse() {
System.out.println("猫抓老鼠");
}
}
public class Dog extends Animal{
@Override
public void sing() {
System.out.println("汪汪汪");
}
}
public class Test {
public static void main(String[] args) {
Animal c = new Cat();
c.sing();
Animal d = new Dog();
d.sing();
Animal e = new Bird();
e.sing();
Cat cat = (Cat)c;
cat.catchMouse();
}
}
笔记补充:面向对象三大特征(封装继承多态)笔记三大特征整理
10.修饰符和单例
一、错题
1、 下面代码的运行结果是( )
public class Arraytest
{
int a[] = new int[6];
public static void main ( String arg[] ) {
System.out.println ( a[0] );
}
}
[单选题]
C 、编译出错 √
2、 下面对静态数据成员的描述中,正确的是 [单选题]
您的回答:
B.静态数据成员不可以被类的对象调用 ×
正确答案:
A、静态数据成员可以在类体内进行初始化 √
3、 下列整型常量 i 的定义中,正确的是( ) [单选题]
您的回答:
B 、static int i; ×
正确答案:
C、static final int i=234; √
简答题
【1】、 用final来修饰属性,方法,类,总结出final的用法;
1.final可以用来修饰类,表示这个类不能被继承。
2.final可以用来修饰变量(不管是类的成员变量还是方法中的局部变量),表示该变量的值不能再改变(即常量)。
3.final还可以用来修饰方法,表示这个方法不能被子类重写。
【2】、 static都可以修饰什么?静态方法与普通方法的区别?静态属性与普通属性的区别?
Static 是静态的修改符;
使用static修饰的属性是类属性,是属于类的,这个属性只有一份,存储在类中,通过类名.属性名进行访问;
使用static修改的方法中不能使用this关键字,在此方法中只能访问类中的静态属性和静态方法;可以通过类名.方法名直接调用;
编程题:
设计一个词典类Dic,每个单词包括英文单词及对应的中文含义,并有一个英汉翻译成员函数,通过查词典的方式将英语翻译成对应的汉语。 思路: 字典项类DicItem包括EngLish(英语单词)、Chinese(对应中文含义)数据成员,字典类包括一个字典项类的列表,包含Add()(添加单词)和trans(英汉翻译)成员函数。
public class Dic {
int size=0;// 单词的数量
DicItem[] items=new DicItem[100];
class DicItem{
String english;
String chinese;
public DicItem(String english, String chinese) {
super();
this.english = english;
this.chinese = chinese;
}
}
//增加一个新单词
public void add(String en,String chi) {
items[size++]=new DicItem(en,chi);
}
//翻译
public String trans(String en) {
for(int i=0;i<size;i++) {
if(items[i].english.equals(en)) {
return items[i].chinese;
}
}
return "无此单词";
}
}
public class TestDic {
public static void main(String[] args) {
Dic dic=new Dic();
dic.add("book", "图书");
dic.add("build", "建构");
dic.add("bit", "位");
dic.add("byte", "字节");
dic.add("bytedance", "字节跳动");
System.out.println(dic.trans("book"));
System.out.println(dic.trans("but"));
System.out.println(dic.trans("bytedance"));
}
}
【编程题】用单例模式编写一个进程管理器的例子。并测试。
public class TaskManager {
private static TaskManager taskManager;
//创建一个当前时间瞬时的 时间对象
private Date date = new Date();
private TaskManager() {
}
public static TaskManager getInstance() {
if(taskManager==null)
taskManager = new TaskManager();
return taskManager;
}
public void find() {
System.out.println("在"+date+"查看任务列表");
}
public void kill(String taskId) {
System.out.println("杀死了"+taskId+"的进程");
}
public static void main(String[] args) {
TaskManager t1 = TaskManager.getInstance();
t1.find();
TaskManager t2 = TaskManager.getInstance();
t2.find();
System.out.println(t1==t2);
}
}