input: Write a function to solve a maze using an object-oriented approach in Python. The function should initialize a Maze object, solve it, and return the shortest path from the start to the end. If the maze is empty, the function should return an empty list.
  
  
  assert solve_maze(3, 3, [[1, 0, 1], [1, 1, 1], [0, 1, 1]]) == [4]
  assert solve_maze(3, 3, [[1, 0, 0], [1, 1, 0], [0, 1, 1]]) == []
  assert solve_maze(3, 3, [[1, 1, 1], [0, 0, 1], [1, 1, 1]]) == [4]
  assert solve_maze(0, 0, []) == []
  assert solve_maze(1, 1, [[1]]) == [0]
  
output: def solve_maze(rows, cols, maze):
      if not maze:
          return []
      
      from collections import deque
      
      class Maze:
          def __init__(self, rows, cols, maze):
              self.rows = rows
              self.cols = cols
              self.maze = maze
              self.directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
          
          def is_valid(self, x, y):
              return 0 <= x < self.rows and 0 <= y < self.cols and self.maze[x][y] == 1
          
          def solve(self):
              start = (0, 0)
              end = (self.rows - 1, self.cols - 1)
              queue = deque([(start, [start[0] * self.cols + start[1]])])
              visited = set()
              visited.add(start)
              
              while queue:
                  (current_x, current_y), path = queue.popleft()
                  
                  if (current_x, current_y) == end:
                      return path
                  
                  for dx, dy in self.directions:
                      new_x, new_y = current_x + dx, current_y + dy
                      if self.is_valid(new_x, new_y) and (new_x, new_y) not in visited:
                          visited.add((new_x, new_y))
                          queue.append(((new_x, new_y), path + [new_x * self.cols + new_y]))
              
              return []
      
      maze_obj = Maze(rows, cols, maze)
      return maze_obj.solve()